how to use okhttp to upload a file?
我使用okhttp作为我的httpclient。 我认为这是一个很好的api,但是文档没有那么详细。
如何使用它通过文件上传发出http发布请求?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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(); } |
我的问题是:
这是一个使用okhttp上传文件和一些任意字段的基本功能(它实际上模拟了常规HTML表单的提交)
更改mime类型以匹配您的文件(此处我假设为.csv),或者如果要上传其他文件类型,则将其作为函数的参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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; } |
注意:由于是异步调用,因此布尔返回类型并不表示上传成功,而仅表示请求已提交到okhttp队列。
这是适用于OkHttp 3.2.0的答案:
1 2 3 4 5 6 7 8 9 10 11 | 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(); } |
注意:此答案适用于okhttp 1.x / 2.x。对于3.x,请参见此其他答案。
来自mimecraft的
1 2 3 4 5 6 7 8 9 10 11 12 | 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(); |
查看多部分/表单数据编码的示例,以了解如何构造这些部分。
一旦有了
由于您似乎正在使用我没有经验的OkHttp API v2.0,所以这只是猜测代码:
1 2 3 4 5 |
对于OkHttp 1.5.4,这是我正在使用的简化代码,它是从示例代码段改编而成的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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) { } } |
1 2 3 4 5 6 7 8 9 | 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(); |
上面的代码将发送用户名,密码作为post参数,并且文件将以"文件"的名称上传。
PHP Server将接收文件
1 2 3 4 5 6 7 | if (isset($_FILES["File"]) && isset($_POST['username']) && isset($_POST['password'])) { //All Values found }else{ echo 'please send the required data'; } |
我为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | 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; } /** * Uses:<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(); } /** * Uses:<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); } } |
完美的代码,可轻松将任何文件以及文件元数据上传到Google驱动器。
[cc lang="java"]
// String url = String.format(" https://www.googleapis.com/upload/drive/v2/files?uploadType=resumable");
布尔状态;
字符串metaDataFile =" {" title":" + step.getFile_name()+""," +
"" description":" + step.getDescription()+""," +
""父母":[{" id":" + step.getFolderId()+" \\ n