Uploading a Large File in Multipart Using Okhttp

Uploading a large file in multipart using OkHttp

From the OkHttp Recipes page, this code uploads an image to Imgur:

private static final String IMGUR_CLIENT_ID = "...";
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

private final OkHttpClient client = new OkHttpClient();

public void run() throws Exception {
// Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"title\""),
RequestBody.create(null, "Square Logo"))
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"image\""),
RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
.build();

Request request = new Request.Builder()
.header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
.url("https://api.imgur.com/3/image")
.post(requestBody)
.build();

Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

System.out.println(response.body().string());
}

You'll need to adapt this to S3, but the classes you need should be the same.

Uploading multiple image files using okhttp v3.2.0

First of all you have a couple of errors in your code

Check the mediatype check places, always the same list element (should be index 1,2,3 etc)

   if (Imagepaths.size() > 1) {
File file = new File(Imagepaths.get(1));

MEDIA_TYPE = Imagepaths.get(0).endsWith("png") ?
MediaType.parse("image/png") : MediaType.parse("image/jpeg");

RequestBody imageBody = RequestBody.create(MEDIA_TYPE, file);
mRequestBody.addFormDataPart("IMAGE2", "IMAGE2", imageBody);
}

Second, mRequestBody.addFormDataPart("IMAGE2", "IMAGE2", imageBody);
do you images have the names IMAGE1,IMAGE2, etc?

Multipart file upload with OkHttp + Spring

You can get a MultipartFile more easier:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String upload(@RequestParam("qqfile") MultipartFile file) throws IOException {
if (!file.isEmpty()) {
// ...
}
return "failure";
}

And then, with OkHttp:

RequestBody body = new MultipartBuilder()
.addFormDataPart("qqfile", filename, RequestBody.create(MediaType.parse("media/type"), new File(filename)))
.type(MultipartBuilder.FORM)
.build();

Request request = new Request.Builder()
.url("/path/to/your/upload")
.post(body)
.build();

OkHttpClient client = new OkHttpClient();
Response response = client.newCall(request).execute();

That worked fine to me.

Be careful with MediaType.parse(filename), you must pass a valid type like text/plain, application/json, application/xml...

Uploading File with okhttp 3.9.0 to REST is giving Error code=422, message=Uprocessable Entity

I had a simple error in my test-id ... it works now ... :)

WRONG:
.addFormDataPart("FK_Person", "1d64b9cc-d405-47c4-9adb-ef276c391ae0&")

OK:
.addFormDataPart("FK_Person", "1d64b9cc-d405-47c4-9adb-ef276c391ae0")

Tracking progress of multipart file upload using OKHTTP

You have to create a custom RequestBody and override writeTo method, and there you have to send your files down the sink in segments. It is very important that you flush the sink after each segment, otherwise your progress bar will fill up quickly without the file being actually sent over the network, because the contents will stay in the sink (which acts like a buffer).

public class CountingFileRequestBody extends RequestBody {

private static final int SEGMENT_SIZE = 2048; // okio.Segment.SIZE

private final File file;
private final ProgressListener listener;
private final String contentType;

public CountingFileRequestBody(File file, String contentType, ProgressListener listener) {
this.file = file;
this.contentType = contentType;
this.listener = listener;
}

@Override
public long contentLength() {
return file.length();
}

@Override
public MediaType contentType() {
return MediaType.parse(contentType);
}

@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(file);
long total = 0;
long read;

while ((read = source.read(sink.buffer(), SEGMENT_SIZE)) != -1) {
total += read;
sink.flush();
this.listener.transferred(total);

}
} finally {
Util.closeQuietly(source);
}
}

public interface ProgressListener {
void transferred(long num);
}

}

You can find a complete implementation that supports displaying progress in an AdapterView and also cancelling uploads at my gist: https://gist.github.com/eduardb/dd2dc530afd37108e1ac

how to use okhttp to upload a file?

Note: this answer is for okhttp 1.x/2.x. For 3.x, see this other answer.

The class Multipart from mimecraft encapsulates the whole HTTP body and can handle regular fields like so:

Multipart m = new Multipart.Builder()
.type(Multipart.Type.FORM)
.addPart(new Part.Builder()
.body("value")
.contentDisposition("form-data; name=\"non_file_field\"")
.build())
.addPart(new Part.Builder()
.contentType("text/csv")
.body(aFile)
.contentDisposition("form-data; name=\"file_field\"; filename=\"file1\"")
.build())
.build();

Take a look at examples of multipart/form-data encoding to get a sense of how you need to construct the parts.

Once you have a Multipart object, all that's left to do is specify the right Content-Type header and pass on the body bytes to the request.

Since you seem to be working with the v2.0 of the OkHttp API, which I don't have experience with, this is just guess code:

// You'll probably need to change the MediaType to use the Content-Type
// from the multipart object
Request.Body body = Request.Body.create(
MediaType.parse(m.getHeaders().get("Content-Type")),
out.toByteArray());

For OkHttp 1.5.4, here is a stripped down code I'm using which is adapted from a sample snippet:

OkHttpClient client = new OkHttpClient();
OutputStream out = null;
try {
URL url = new URL("http://www.example.com");
HttpURLConnection connection = client.open(url);
for (Map.Entry<String, String> entry : multipart.getHeaders().entrySet()) {
connection.addRequestProperty(entry.getKey(), entry.getValue());
}
connection.setRequestMethod("POST");
// Write the request.
out = connection.getOutputStream();
multipart.writeBodyTo(out);
out.close();

// Read the response.
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Unexpected HTTP response: "
+ connection.getResponseCode() + " " + connection.getResponseMessage());
}
} finally {
// Clean up.
try {
if (out != null) out.close();
} catch (Exception e) {
}
}


Related Topics



Leave a reply



Submit