60

I use okhttp to be my httpclient. I think it's a good api but the doc is not so detailed.

how to use it to make a http post request with file uploading?

public Multipart createMultiPart(File file){ Part part = (Part) new Part.Builder().contentType("").body(new File("1.png")).build(); //how to set part name? Multipart m = new Multipart.Builder().addPart(part).build(); return m; } public String postWithFiles(String url,Multipart m) throws IOException{ ByteArrayOutputStream out = new ByteArrayOutputStream(); m.writeBodyTo(out) ; Request.Body body = Request.Body.create(MediaType.parse("application/x-www-form-urlencoded"), out.toByteArray()); Request req = new Request.Builder().url(url).post(body).build(); return client.newCall(req).execute().body().string(); } 

my question is:

  1. how to set part name? in the form, the file should be named file1.
  2. how to add other fields in the form?
7
  • do you have any success with it ? i want to upload multiple files Commented May 19, 2014 at 7:49
  • not yet..i search for some days ,and doesn't get any result. Commented May 19, 2014 at 12:25
  • I am using different approach because Volley is not designed for uploading. I have watched Google I/O. try using Loopj Commented May 20, 2014 at 1:29
  • I had noticed this lib.It seems that can only run in android vm? The benefit of okhttp is running in Sun's Java vm.It's easy to do unit test.Could you run loopj out of android VM? Commented May 20, 2014 at 8:25
  • what error do you get? Commented May 20, 2014 at 17:32

7 Answers 7

53

Here is a basic function that uses okhttp to upload a file and some arbitrary field (it literally simulates a regular HTML form submission)

Change the mime type to match your file (here I am assuming .csv) or make it a parameter to the function if you are going to upload different file types

 public static Boolean uploadFile(String serverURL, File file) { try { RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM) .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("text/csv"), file)) .addFormDataPart("some-field", "some-value") .build(); Request request = new Request.Builder() .url(serverURL) .post(requestBody) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(final Call call, final IOException e) { // Handle the error } @Override public void onResponse(final Call call, final Response response) throws IOException { if (!response.isSuccessful()) { // Handle the error } // Upload successful } }); return true; } catch (Exception ex) { // Handle the error } return false; } 

Note: because it is async call, the boolean return type does not indicate successful upload but only that the request was submitted to okhttp queue.

Sign up to request clarification or add additional context in comments.

5 Comments

Does it add Content-Length header automatically?
Note: For unresolved class names, check this link
I've spent two days trying to upload a file from Android to an Asp.Net MVC HttpPost action method. The other, more basic, java solutions made the connection but failed with the file upload - and were almost impossible to debug. This was the solution that finally worked!
BUT, when I upgraded okhttp to 3.5.0 it no longer compiled. See comment above by mr5 for resolving links, and answer below by @Bryant Kou for changed class names.
where you use text/csv What will i use for mp3 file or jpg ? is there any random or auto method which work on all type of files ?
53

Here's an answer that works with OkHttp 3.2.0:

public void upload(String url, File file) throws IOException { OkHttpClient client = new OkHttpClient(); 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(); } 

1 Comment

OkHttpClient client = new OkHttpClient();
23

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) { } } 

4 Comments

It worked by changing " Request.Body body = Request.Body.create(MediaType.parse("application/x-www-form-urlencoded"), out.toByteArray());" to "Request.Body.create(MediaType.parse(m.getHeaders().get("Content-Type"))"
what dependency should I add for Multipart?
@jawanam If you're using OkHttp 3.x, then an equivalent class is already included in OkHttp. See the other answer for its usage. The Mulitpart in this answer refers to mimecraft's.
this answer is to old
3

I've created cool helper class for OkHttp3. it here

public class OkHttp3Helper { public static final String TAG; private static final okhttp3.OkHttpClient client; static { TAG = OkHttp3Helper.class.getSimpleName(); client = new okhttp3.OkHttpClient.Builder() .readTimeout(7, TimeUnit.MINUTES) .writeTimeout(7, TimeUnit.MINUTES) .build(); } private Context context; public OkHttp3Helper(Context context) { this.context = context; } /** * <strong>Uses:</strong><br/> * <p> * {@code * ArrayMap<String, String> formField = new ArrayMap<>();} * <br/> * {@code formField.put("key1", "value1");}<br/> * {@code formField.put("key2", "value2");}<br/> * {@code formField.put("key3", "value3");}<br/> * <br/> * {@code String response = helper.postToServer("http://www.example.com/", formField);}<br/> * </p> * * @param url String * @param formField android.support.v4.util.ArrayMap * @return response from server in String format * @throws Exception */ @NonNull public String postToServer(@NonNull String url, @Nullable ArrayMap<String, String> formField) throws Exception { okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder().url(url); if (formField != null) { okhttp3.FormBody.Builder formBodyBuilder = new okhttp3.FormBody.Builder(); for (Map.Entry<String, String> entry : formField.entrySet()) { formBodyBuilder.add(entry.getKey(), entry.getValue()); } requestBuilder.post(formBodyBuilder.build()); } okhttp3.Request request = requestBuilder.build(); okhttp3.Response response = client.newCall(request).execute(); if (!response.isSuccessful()) { throw new IOException(response.message()); } return response.body().string(); } /** * <strong>Uses:</strong><br/> * <p> * {@code * ArrayMap<String, String> formField = new ArrayMap<>();} * <br/> * {@code formField.put("key1", "value1");}<br/> * {@code formField.put("key2", "value2");}<br/> * {@code formField.put("key3", "value3");}<br/> * <br/> * {@code * ArrayMap<String, File> filePart = new ArrayMap<>();} * <br/> * {@code filePart.put("key1", new File("pathname"));}<br/> * {@code filePart.put("key2", new File("pathname"));}<br/> * {@code filePart.put("key3", new File("pathname"));}<br/> * <br/> * {@code String response = helper.postToServer("http://www.example.com/", formField, filePart);}<br/> * </p> * * @param url String * @param formField android.support.v4.util.ArrayMap * @param filePart android.support.v4.util.ArrayMap * @return response from server in String format * @throws Exception */ @NonNull public String postMultiPartToServer(@NonNull String url, @Nullable ArrayMap<String, String> formField, @Nullable ArrayMap<String, File> filePart) throws Exception { okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder().url(url); if (formField != null || filePart != null) { okhttp3.MultipartBody.Builder multipartBodyBuilder = new okhttp3.MultipartBody.Builder(); multipartBodyBuilder.setType(okhttp3.MultipartBody.FORM); if (formField != null) { for (Map.Entry<String, String> entry : formField.entrySet()) { multipartBodyBuilder.addFormDataPart(entry.getKey(), entry.getValue()); } } if (filePart != null) { for (Map.Entry<String, File> entry : filePart.entrySet()) { File file = entry.getValue(); multipartBodyBuilder.addFormDataPart( entry.getKey(), file.getName(), okhttp3.RequestBody.create(getMediaType(file.toURI()), file) ); } } requestBuilder.post(multipartBodyBuilder.build()); } okhttp3.Request request = requestBuilder.build(); okhttp3.Response response = client.newCall(request).execute(); if (!response.isSuccessful()) { throw new IOException(response.message()); } return response.body().string(); } private okhttp3.MediaType getMediaType(URI uri1) { Uri uri = Uri.parse(uri1.toString()); String mimeType; if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { ContentResolver cr = context.getContentResolver(); mimeType = cr.getType(uri); } else { String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri .toString()); mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension( fileExtension.toLowerCase()); } return okhttp3.MediaType.parse(mimeType); } } 

Comments

3
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).writeTimeout(180, TimeUnit.SECONDS).readTimeout(180, TimeUnit.SECONDS).build(); RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) .addFormDataPart("File", path.getName(),RequestBody.create(MediaType.parse("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),path)) .addFormDataPart("username", username) .addFormDataPart("password", password) .build(); Request request = new Request.Builder().url(url).post(body).build(); Response response = client.newCall(request).execute(); result = response.body().string(); 

Above code will send the username, password as the post parameter and the file will be uploaded in the name of "File".

PHP Server will receive the files

 if (isset($_FILES["File"]) && isset($_POST['username']) && isset($_POST['password'])) { //All Values found }else{ echo 'please send the required data'; } 

Comments

1

Perfect code for uploading any files to google drive along with metadata of files easily.

 String url = String.format("https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart"); //String url = String.format("https://www.googleapis.com/upload/drive/v2/files?uploadType=resumable"); boolean status; String metaDataFile = "{\"title\":\"" + step.getFile_name() + "\"," + "\"description\":\"" + step.getDescription() + "\"," + "\"parents\":[{\"id\":\"" + step.getFolderId() + "\"}]," + "\"capabilities\":{\"canEdit\":\"" + false + "\", \"canDownload\":\" "+ false +" \" }, " + "\"type\":\"" + step.getFile_access() + "\"" + "}"; //get the encoded byte data for decode byte[] file = Base64.decodeBase64(step.getFile_data()); //attaching metadata to our request object RequestBody requestBodyMetaData = RequestBody.create(MediaType.parse("application/json"), metaDataFile); //passing both meta data and file content for uploading RequestBody requestBodyMultipart = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("metadata", null, requestBodyMetaData) .addFormDataPart("file", null, RequestBody.create(MediaType.parse("application/octet-stream"), file)) .build(); Request request = new Request.Builder() .url(url) .addHeader("Authorization", String.format("Bearer %s", step.getAccess_token())) .post(requestBodyMultipart) .build(); OkHttpClient okHttpClient = new OkHttpClient(); try { // Get response after rest call. Response response = okHttpClient.newCall(request).execute(); status = response.code() == 200 ? true : false; map.put(step.getOutput_variable(), response.code()); 

1 Comment

Welcome to Stack Overflow. While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. How to Answer
1

Asynchronously ...

public void UploadFileFromOkhttp(String filePath, String jwtToken){ String url = "https://api.baserow.io/api/user-files/upload-file/"; MultipartBody.Builder builder = new MultipartBody.Builder(); builder.setType(MultipartBody.FORM); File file = new File(filePath); builder.addFormDataPart("file" , file.getName() , RequestBody.create(MediaType.parse("image/*"), file)); RequestBody requestBody = builder.build(); Request request = new Request.Builder() .url(url) .addHeader("Authorization", "JWT "+ jwtToken) .post(requestBody) .build(); okHttpClient.newCall(request).enqueue(new okhttp3.Callback() { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { activity.runOnUiThread(new Runnable() { @Override public void run() { OnError(e.getMessage()); } }); } @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { final String responseData = response.body().string(); activity.runOnUiThread(new Runnable() { @Override public void run() { OnSuccess(responseData); } }); } }); 

}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.