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
Related
I was trying to implement postman's working as following for android app:
Here is my java codes:
MediaType CONTENT_TYPE = MediaType.parse("application/x-www-form-urlencoded");
RequestBody requestBody = new MultipartBody.Builder()
.setType(CONTENT_TYPE)
.addFormDataPart("phoneNumber", phone)
.addFormDataPart("serviceType", type)
.addFormDataPart("stripeToken", token)
.addFormDataPart("serviceCost", String.valueOf(amount))
.build();
final Request request = new Request.Builder()
.url(Const.URL_HEROKU_BASE+"payment/charge")
.post(requestBody)
.build();
It makes crash ...
I had the same issue when using the public api/login of this free rest service.
In postman, when passing body as application/x-www-form-urlencoded works. But in OkHttp3 MultipartBody doesn't work.
As #shindi suggested this code works perfectly for this api.
RequestBody requestBody = new FormBody.Builder()
.add("email", "some_email")
.add("password", "some_password")
.build();
.header() wasn't needed for the request either. Works for me. Hope it helps.
Change:
MultipartBody
to:
FormBody
I think you are not adding the content type properly:
Change this:
final Request request = new Request.Builder()
.url(Const.URL_HEROKU_BASE+"payment/charge")
.post(requestBody)
.build();
to:
final Request request = new Request.Builder()
.header("Content-Type", "application/x-www-form-urlencoded")
.url(Const.URL_HEROKU_BASE+"payment/charge")
.post(requestBody)
.build();
and remove the .setType(CONTENT_TYPE) part.
Let use FormBody as suggested at https://stackoverflow.com/a/53261129/2013887
And don't forget to use correct #RequestBody type, e.g MultiValueMap for application/x-www-form-urlencoded media type
Generated the code below by postman:
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("multipart/form-data; boundary=---011000010111000001101001");
RequestBody body = RequestBody.create(mediaType, "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"[object Object]\"\r\nContent-Type: false\r\n\r\n\r\n-----011000010111000001101001--");
Request request = new Request.Builder()
.url("http://foobar.com/newsfeed/photo")
.post(body)
.addHeader("content-type", "multipart/form-data; boundary=---011000010111000001101001")
.addHeader("x-access-token", "MczCvMEbllNhGaMwEDnGXuQjrwBAYuYleFlgsUZDWRYbVaohpEGgofonYcvHsgPaTnbzHxCvJWalYFTY")
.addHeader("accept-language", "ru")
.build();
Response response = client.newCall(request).execute();
This request make a file on Server with 0 Kb size. and I couldn't put a file. So, I have to put a file like this:
RequestBody body = RequestBody.create(mediaType, new File(filename));
But I got TimeOutExaption.
How to put a file by this kind of Rest API?
I found a way to multipart file upload by Ion.
Ion.with(context).load(url).setHeader("x-access-token", token)
.setMultipartParameter("x-access-token", token)
.setMultipartContentType("multipart/form-data")
.setMultipartFile("image", "image/jpeg", file)
.asString().withResponse().setCallback(new FutureCallback<Response<String>>() {
#Override
public void onCompleted(Exception e, Response<String> result) {
if (result != null)
onSuccess(result.getResult(), result.getHeaders().code());
}
});
Rest API:
I am getting following exception in between of upload when trying to upload a large video file(~140mb) with using retrofit 2.0. Small files are going through fine.
javax.net.ssl.SSLException: Write error: ssl=0xb924ef28: I/O error during system call, Broken pipe
at com.android.org.conscrypt.NativeCrypto.SSL_write(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:771)
at okio.Okio$1.write(Okio.java:80)
at okio.AsyncTimeout$1.write(AsyncTimeout.java:155)
at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
at okio.RealBufferedSink.write(RealBufferedSink.java:46)
at okhttp3.internal.http.Http1xStream$FixedLengthSink.write(Http1xStream.java:286)
at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
at okio.RealBufferedSink.writeAll(RealBufferedSink.java:104)
at okhttp3.RequestBody$3.writeTo(RequestBody.java:118)
at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:171)
at okhttp3.MultipartBody.writeTo(MultipartBody.java:113)
at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:704)
at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)
at okhttp3.RealCall.getResponse(RealCall.java:241)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
here is how I am creating multipart/form data
File originalFile = new File(attachment.getFilePath());
RequestBody requestFile
= RequestBody.create(MediaType.parse("multipart/form-data"), originalFile);
MultipartBody.Part body
= MultipartBody.Part.createFormData("file", attachment.getUuid(), requestFile);
Call<ResponseBody> call
= FileAPIProvider.getService().upload(attachment.getUuid(),
attachment.getUuid(),
attachment.getMimeType(),
body,
attachment.getVirtualPath());
Retrofit adapter setup
builder.connectTimeout(30, TimeUnit.SECONDS);
builder.readTimeout(60, TimeUnit.MINUTES);
builder.writeTimeout(60, TimeUnit.MINUTES);
// Add headers
builder.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String token = LocalStorage.getInstance().getToken();
request = request.newBuilder()
.addHeader("Authorization", token)
.build();
return chain.proceed(request);
}
});
sRetrofit = new Retrofit.Builder()
.baseUrl(BuildConfig.FILE_URL)
.client(builder.build())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
I am pretty sure that my network connection is stable enough.
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
}
I'm using OkHTTP for making a post request to my server. I know I can build a request like this:
RequestBody formBody = new FormEncodingBuilder()
.add("param1", param1)
.build();
Request request = new Request.Builder()
.url(url)
.post(formBody)
.build();
So what I want to do is to add the parameters dynamically. E.g:
RequestBody formBody = new FormEncodingBuilder()
for (ParamsArray m : requestParams) {
formBody.add("param1", requestParams.value);
}
But there's no function add for a RequestBody and I don't know if it is possible to convert a FormEncodingBuilder to a RequestBody.
Thank you!
A FormEncodingBuilder will turn into a RequestBody when you build it. Looking at the documentation, something like this ought to work.
FormEncodingBuilder formBodyBuilder = new FormEncodingBuilder()
for (ParamsArray m : requestParams) {
formBodyBuilder.add("param1", requestParams.value);
}
RequestBody body = formBodyBuilder.build()
The documentation is available here:
https://square.github.io/okhttp/2.x/okhttp/com/squareup/okhttp/FormEncodingBuilder.html
As of 3.0.0, the FormEncodingBuilder is gone:
Form and Multipart bodies are now modeled. We've replaced the opaque
FormEncodingBuilder with the more powerful FormBody and
FormBody.Builder combo. Similarly we've upgraded MultipartBuilder into
MultipartBody, MultipartBody.Part, and MultipartBody.Builder.
So replace with FormBody.Builder for these versions.
try this
FormEncodingBuilder formBodyBuilder = new FormEncodingBuilder();
for (ParamsArray m : requestParams) {
formBodyBuilder.add("param1", requestParams.value);
}
RequestBody formBody = formBodyBuilder.build();
Request request = new Request.Builder()
.url(url)
.post(formBody)
.build();
Instead of FormEncodingBuilder
use
Builder paramBuilder = new FormBody.Builder();
paramBuilder.add("param1","value1");
paramBuilder.add("param2","value2");
RequestBody requestBody = paramBuilder.build();