我正在完成这个使用okhttp与web服务进行通信的项目。
对于常规GET和POST,一切正常,但我无法正确上传文件。
okhttp文档非常缺乏这些主题,我在这里或任何地方找到的所有东西似乎都不适用于我的情况。
它应该很简单:我必须发送文件和一些字符串值。但我无法弄清楚如何做到这一点。
根据我发现的一些样本,我首先尝试了这个:
RequestBody requestBody = new MultipartBuilder().type(MultipartBuilder.FORM)
.addFormDataPart("group", getGroup())
.addFormDataPart("type", getType())
.addFormDataPart("entity", Integer.toString(getEntity()))
.addFormDataPart("reference", Integer.toString(getReference()))
.addPart(Headers.of("Content-Disposition", "form-data; name=\"task_file\""), RequestBody.create(MediaType.parse("image/png"), getFile()))
.build();
它给我一个“400错误请求”错误。
所以我从okhttp食谱中尝试了这个:
RequestBody requestBody = new MultipartBuilder().type(MultipartBuilder.FORM)
.addPart(Headers.of("Content-Disposition", "form-data; name=\"group\""), RequestBody.create(null, getGroup()))
.addPart(Headers.of("Content-Disposition", "form-data; name=\"type\""), RequestBody.create(null, getType()))
.addPart(Headers.of("Content-Disposition", "form-data; name=\"entity\""), RequestBody.create(null, Integer.toString(getEntity())))
.addPart(Headers.of("Content-Disposition", "form-data; name=\"reference\""), RequestBody.create(null, Integer.toString(getReference())))
.addPart(Headers.of("Content-Disposition", "form-data; name=\"task_file\""), RequestBody.create(MediaType.parse("image/png"), getFile()))
.build();
同样的结果。
不知道还有什么可以尝试或调查这个。
请求使用以下代码完成:
// adds the required authentication token
Request request = new Request.Builder().url(getURL()).addHeader("X-Auth-Token", getUser().getToken().toString()).post(requestBody).build();
Response response = client.newCall(request).execute();
但我很确定问题是如何建立请求体。
我做错了什么?
编辑:顺便说一句,上面的“getFile()”返回一个File对象。其余参数都是字符串和整数。
答案 0 :(得分:20)
我在初次发布后找到了自己的问题答案。
我会把它留在这里,因为它对其他人有用,因为有很多okhttp上传示例:
RequestBody requestBody = new MultipartBuilder().type(MultipartBuilder.FORM)
.addFormDataPart("group", getGroup())
.addFormDataPart("type", getType())
.addFormDataPart("entity", Integer.toString(getEntity()))
.addFormDataPart("reference", Integer.toString(getReference()))
.addFormDataPart("task_file", "file.png", RequestBody.create(MediaType.parse("image/png"), getFile()))
.build();
没有理由将“addPart”与“Headers.of”等一起使用,就像在食谱中一样,addFormDataPart可以解决问题。
对于文件字段本身,它需要3个参数:name,filename,然后是文件体。就是这样。
答案 1 :(得分:6)
我刚刚更改addFormDataPart
而不是addPart
,最后使用以下代码解决了我的问题:
/**
* Upload Image
*
* @param memberId
* @param sourceImageFile
* @return
*/
public static JSONObject uploadImage(String memberId, String sourceImageFile) {
try {
File sourceFile = new File(sourceImageFile);
Log.d(TAG, "File...::::" + sourceFile + " : " + sourceFile.exists());
final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart("member_id", memberId)
.addFormDataPart("file", "profile.png", RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
.build();
Request request = new Request.Builder()
.url(URL_UPLOAD_IMAGE)
.post(requestBody)
.build();
OkHttpClient client = new OkHttpClient();
Response response = client.newCall(request).execute();
return new JSONObject(response.body().string());
} catch (UnknownHostException | UnsupportedEncodingException e) {
Log.e(TAG, "Error: " + e.getLocalizedMessage());
} catch (Exception e) {
Log.e(TAG, "Other Error: " + e.getLocalizedMessage());
}
return null;
}
答案 2 :(得分:2)
使用此 AsyncTask
<强> SignupWithImageTask 强>
public class SignupWithImageTask extends AsyncTask<String, Integer, String> {
ProgressDialog progressDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(SignupActivity.this);
progressDialog.setMessage("Please Wait....");
progressDialog.show();
}
@Override
protected String doInBackground(String... str) {
String res = null;
try {
// String ImagePath = str[0];
String name = str[0], email = str[1], dob = str[2], IMEI = str[3], phone = str[4], ImagePath = str[5];
File sourceFile = new File(ImagePath);
Log.d("TAG", "File...::::" + sourceFile + " : " + sourceFile.exists());
final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/*");
String filename = ImagePath.substring(ImagePath.lastIndexOf("/") + 1);
/**
* OKHTTP2
*/
// RequestBody requestBody = new MultipartBuilder()
// .type(MultipartBuilder.FORM)
// .addFormDataPart("member_id", memberId)
// .addFormDataPart("file", "profile.png", RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
// .build();
/**
* OKHTTP3
*/
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", filename, RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
.addFormDataPart("result", "my_image")
.addFormDataPart("name", name)
.addFormDataPart("email", email)
.addFormDataPart("dob", dob)
.addFormDataPart("IMEI", IMEI)
.addFormDataPart("phone", phone)
.build();
Request request = new Request.Builder()
.url(BASE_URL + "signup")
.post(requestBody)
.build();
OkHttpClient client = new OkHttpClient();
okhttp3.Response response = client.newCall(request).execute();
res = response.body().string();
Log.e("TAG", "Response : " + res);
return res;
} catch (UnknownHostException | UnsupportedEncodingException e) {
Log.e("TAG", "Error: " + e.getLocalizedMessage());
} catch (Exception e) {
Log.e("TAG", "Other Error: " + e.getLocalizedMessage());
}
return res;
}
@Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
if (progressDialog != null)
progressDialog.dismiss();
if (response != null) {
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getString("message").equals("success")) {
JSONObject jsonObject1 = jsonObject.getJSONObject("data");
SharedPreferences settings = getSharedPreferences("preference", 0); // 0 - for private mode
SharedPreferences.Editor editor = settings.edit();
editor.putString("name", jsonObject1.getString("name"));
editor.putString("userid", jsonObject1.getString("id"));
editor.putBoolean("hasLoggedIn", true);
editor.apply();
new UploadContactTask().execute();
startActivity(new Intent(SignupActivity.this, MainActivity.class));
} else {
Toast.makeText(SignupActivity.this, "" + jsonObject.getString("message"), Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(SignupActivity.this, "Something Went Wrong", Toast.LENGTH_SHORT).show();
}
}
}
答案 3 :(得分:0)
以下是使用okhttp3上传文件的方法。
try {
UpdateInformation("yourEmailAddress", filePath, sourceFile);
} catch (IOException e) {
e.printStackTrace();
}
private void UploadInformation(String email, final String _filePath, final File file) throws IOException {
runOnUiThread(new Runnable() {
@Override
public void run() {
//show progress bar here
}
});
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.build();
String mime = getMimeType(_filePath);
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(),
RequestBody.create(MediaType.parse(mime), file))
.addFormDataPart("email", email)
.build();
okhttp3.Request request = new okhttp3.Request.Builder()
.url("yourEndPointURL")
.post(body)
.addHeader("authorization", "yourEndPointToken")
.addHeader("content-type", "application/json")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
call.cancel();
runOnUiThread(new Runnable() {
@Override
public void run() {
//hide progress bar here
}
});
}
@Override
public void onResponse(Call call, okhttp3.Response response) throws IOException {
try {
final String myResponse = response.body().string();
runOnUiThread(new Runnable() {
@Override
public void run() {
//hide progress bar here
//Cont from here
//Handle yourEndPoint Response.
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private String getMimeType(String path) {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String contentTypeFor = fileNameMap.getContentTypeFor(path);
if (contentTypeFor == null)
{
contentTypeFor = "application/octet-stream";
}
return contentTypeFor;
}
希望这会有所帮助。