I'm writing an android app that needs to communicate with a server. I'm struggling to make a MultipartBody for OkHttp3 to use. My code looks like this:
OkHttpClient client = new OkHttpClient();
try
{
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("someKey1", "someString1")
.addFormDataPart("someKey2", "someString2")
.build();
System.out.println(requestBody.toString());
Request request = new Request.Builder()
.url("server url")
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
return response;
}
catch (IOException e)
{
e.printStackTrace();
return false;
}
This is pretty much the standard code everyone uses. The server receives the request, but I can't get the MultipartBody from the request. When the multipart body is printed, it looks like this:
I/System.out: okhttp3.MultipartBody#14040826
So my questions are: Why doesn't it contain my data and should it? Am I missing a library (I included compile 'com.squareup.okhttp3:okhttp:3.2.0' in the gradle and assume MultipartBody is part of this library)? What is a MultipartBody supposed to look like?
I tried sending a FormBody as well but it looks the same.
Remove okhttp3.Response response = client.newCall(request).execute();
okhttp3.Call call = client.newCall(request);
call.enqueue(new okhttp3.Callback() {
#Override
public void onFailure(okhttp3.Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
}
});
Related
I use OKHTTP3 library to upload files to my http file server.
I found this code to do this and it works fine.
But I also want to just create a new folder without file.
Does anybody know how to create the request?
OkHttpClient client = new OkHttpClient.Builder()
.authenticator(new Authenticator() {
#Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic(username,password);
return response.request().newBuilder()
.header("Authorization", credential)
.build();
}
})
.build();
RequestBody formBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(),
RequestBody.create(MediaType.parse("text/plain"), file))
.addFormDataPart("other_field", "other_field_value")
.build();
Request request = new Request.Builder().url(url).post(formBody).build();
Response response = client.newCall(request).execute();
My Http File Server is in default configuration.
I didn't set up any script, because I don't understand the process(see on https://rejetto.com/wiki/index.php?title=HFS:_Event_scripts)
Thank you
I need to get the XML file from the site. I'm learning to use Retrofit.
I need to make a request and attach my API key via the "X-AppId" header. It should look like this:
X-AppId: my key.
If I do this from the browser, I get the answer.
Through the retrofit I get the access
error 403 Forbidden code = 403, message = Forbidden, url = https: //
Tell me how it is implemented properly to receive an answer from the server code = 200
Here is my implementation:
public interface myAPIinterface {
#GET("/api/ru/index/route/?from=Minsk&to=Warsaw")
Call<Routes> getProducts();
}
This is the activity where I output to the log:
private void getProducts(){
final ProgressDialog loading = ProgressDialog.show(this,"Fetching Data","Please wait...",false,false);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
Log.d(TAG, "getProducts");
httpClient.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.addHeader("X-AppId:", "97377f7b702d7198e47a2bf12eec74")
.build();
return chain.proceed(request);
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://rasp.rw.by")
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
myAPIinterface api = retrofit.create(myAPIinterface.class);
Call<Routes> call = api.getProducts();
call.enqueue(new Callback<Routes>() {
#Override
public void onResponse(#NonNull Call<Routes> call, #NonNull Response<Routes> response) {
Log.d(TAG, "onResponse");
Log.d(TAG, String.valueOf(kk));
Log.d(TAG, String.valueOf(response));
loading.dismiss();}
#Override
public void onFailure(Call<Routes> call, Throwable throwable) {
loading.dismiss();
Log.d(TAG, "onFailure" + throwable);
}
});
this is a log:
Response{protocol=http/1.1, code=403, message=Forbidden,
url=https://rasp.rw.by/api/ru/index/route/?from=Minsk&to=Warsaw}
if I take third-party sites where there are no headers, I get a response of 200 without problems. What am I doing wrong in this case? Thank you.
Oh, man, what are you doing. You can use annotations like #Query, #Header, etc.
public interface myAPIinterface {
#GET("/api/ru/index/route")
Call<Routes> getProducts(#Header("X-AppId:") String YOUR_APP_ID,
#Query("from") String from,
#Query("to") String to)
}
Then you can create request like this:
Retrofit retrofit = new Retrofit.Builder().
.baseUrl("https://rasp.rw.by")
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
retrofit.create(myAPIinterface.class).getProducts(myId, "Minsk", "Warsaw").enqueue ...
How It can help? You forgot to add header at second retrofit and then you have 403 error. So, You must add annotations, and this will be the last mistake when you forgot to put value to header/query/etc.
I am sending Json String to my webapi php file from Android Using OkHttpClient from background Service.
The Code of Web Service Is
if (isset($_POST)) {
$data = json_decode(file_get_contents('php://input'), true);
}
The Android Code is :
String requestString = jsonObject.toString();
URL url = new URL("http://cbs.octa.in/webapis/InsertData.php");
OkHttpClient client = new OkHttpClient();
MediaType mdt = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, requestString);
Request request = new Request.Builder()
.url(url)
.header("Content-Type","application/json")
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.v("BGAPI", "RESPONSE ERROR " + e.getMessage());
}
#Override
public void onResponse(Call call, Response response) throws IOException {
Log.v("BGAPI", "RESPONSE " + response);
}
});
The output for this call i am getting is :
RESPONSE ERROR Unable to resolve host "cbs.octa.in": No address associated with hostname
I tried this call from postman and its working , even i confirmed by entering the same url in broweser.
My question is to send data to server in that web api. Please guide me.
Note : For Privacy i have not given the actual domain name.
I am building an Android APP where I use the Internet Game Database API through Mashape market place. I am using Retrofit for the get requests and getting data from the API requires an API key.
I got it to work but the API only return game ids and I want the game names and other information, but I am not sure how to add the fields. This is how Mashape query it:
HttpResponse<String> response = Unirest.get("https://igdbcom-internet-game-database-v1.p.mashape.com/games/?fields=name%2Crelease_dates")
.header("X-Mashape-Key", "API KEY HERE")
.header("Accept", "application/json")
.asString();
and this is my Retrofit Interface
public interface GamesAPIService {
#GET("/games/")
Call<List<GamesResponse>> gameList(#Query("mashape-key") String apikey);
}
I tried to use this
#GET("/games/?fields=name,release_dates")
But no luck, I also tried with #Field but didn't work either. Any ideas? Thanks.
Edit: Just to clarify when I add the "?fields=name,release_dates" I get 401 Unauthorized Error.
Firstly I think you need to add mashape key to all your request.
OkHttpClient httpClient = new OkHttpClient();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("X-Mashape-Key", "API_KEY_HERE")
.addHeader("Accept", "application/json")
.build();
return chain.proceed(request);
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://igdbcom-internet-game-database-v1.p.mashape.com")
.client(httpClient)
.build();
And then this is information query.
public interface GamesAPIService {
#GET("/games")
Call<List<GamesResponse>> gameList(#Query("fields") String value);
}
And last thing for calling.
GamesAPIService gamesAPIService = retrofit.create(GamesAPIService.class);
Call<List<GamesResponse>> call = gamesAPIService.gameList("name,release_dates");
if (call!=null){
call.enqueue(new Callback<List<GamesResponse>>() {
#Override
public void onResponse(Call<List<GamesResponse>> call, Response<List<GamesResponse>> response) {
// handle success
}
#Override
public void onFailure(Throwable t) {
// handle failure
}
});
}
I'm trying to upload a file to the server using multipart form.
Since API 23 Android has deprecated the Apache HTTP library.
I switched to using OkHttp to do my file uploads like so:
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(name, fileName, requestBodyPart)
.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
And the requestBodyPart is:
requestBodyPart = new RequestBody() {
#Override
public MediaType contentType() {
return MediaType.parse(contentType);
}
#Override
public void writeTo(BufferedSink sink) throws IOException {
try {
if (sink.writeAll(Okio.source(inputStream)) == 0) {
throw new IOException("Empty File!");
}
} finally {
MiscUtils.closeCloseable(inputStream);
}
}
};
However, it seems like OkHttp is not that great when it comes to file uploads. Lots of timeouts and seems to be creating several layers of abstractions (sources and sinks) and has this AsyncTimeout that fires while the file data is still being written over the socket.
Are there any recommendations for doing Multipart File Uploads from Android that work with API 23 onwards. I know I can include the HTTP legacy library but since it was removed I would prefer not to do that. Or is there a way I can improve the performance of OkHttp?
This should work
String name = ...
File file = ...
MediaType mediaType = MediaType.parse(...)
OkHttpClient httpClient = ...
Request request = new Request.Builder()
.url(url)
.post(new MultipartBuilder().type(MultipartBuilder.FORM)
.addFormDataPart(name,
file.getName(),
RequestBody.create(mediaType, file))
.build())
.build();
try {
Response response = httpClient.newCall(request).execute();
} catch (IOException e) {
// handle error
}