[英]how to use okhttp to upload a file?
我使用 okhttp 作为我的 httpclient。 我认为这是一个很好的 api,但文档不是那么详细。
如何使用它来发出带有文件上传的 http post 请求?
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),或者如果您要上传不同的文件类型,则将其作为函数的参数
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 的答案:
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 中的Multipart
类封装了整个 HTTP 主体,可以像这样处理常规字段:
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();
查看multipart/form-data 编码的示例,以了解您需要如何构建部件。
一旦有了Multipart
对象,剩下要做的就是指定正确的Content-Type
标头并将正文字节传递给请求。
由于您似乎正在使用我没有经验的 OkHttp API 的 v2.0,因此这只是猜测代码:
// 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());
对于 OkHttp 1.5.4,这是我正在使用的精简代码,该代码改编自示例片段:
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) {
}
}
我为OkHttp3
创建了很酷的助手类。 在这里
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);
}
}
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 服务器将接收文件
if (isset($_FILES["File"]) &&
isset($_POST['username']) &&
isset($_POST['password'])) {
//All Values found
}else{
echo 'please send the required data';
}
将任何文件连同文件元数据轻松上传到谷歌驱动器的完美代码。
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());
异步...
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);
}
});
}
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.