Retrofit 2不能上传带有两个额外单独字符串参数的文件 [英] Retrofit 2 can't upload a file with two additional separate string parameters
问题描述
阅读编辑问题底部的可能替代解决方案,直到找到解决方案。
是一个使用POSTMan的两个参数的成功的文件。我正在试图做同样的改造,但收到BadRequest。
PostMan设置:
$ b
现在,我在Android中如何做到这一点,但没有成功:
改造服务接口
@Multipart
@POST(jobDocuments / upload)
呼叫< ResponseBody>上传(@Part(文件)MultipartBody.Part文件,@ Part(文件夹)MultipartBody.Part文件夹,@ Part(名称)MultipartBody.Part名称);
这是我的@Background方法,用以上服务生成的网络请求运行
CustDataClient服务=
ServiceGenerator.createService(CustDataClient.class);
File file = new File(fileUri.getPath());
//从文件
创建RequestBody实例RequestBody requestFile =
RequestBody.create(MediaType.parse(multipart / form-data),file);
MultipartBody.Part fileData =
MultipartBody.Part.createFormData(file,fileName,requestFile);
MultipartBody.Part文件夹=
MultipartBody.Part.createFormData(folder,LeadDocuments);
MultipartBody.Part name =
MultipartBody.Part.createFormData(name,fileName);
//最后,执行请求
调用< ResponseBody> call = service.upload(fileData,folder,name);
尝试{
响应< ResponseBody> rr = call.execute();
ResponseBody empJobDocsResult = rr.body(); // Bad Request here :(
Log.v(Upload,success);
} catch(Exception ex){
Log.e(Upload error:,ex.getMessage());
}
[Route(upload)]
[HttpPost]
public IHttpActionResult上传()
{
if(HttpContext.Current.Request.Files.AllKeys.Any())
{
/ /从Files集合获取上传的图像
var httpPostedFile = HttpContext.Current.Request.Files [file];
if(httpPostedFile!= null)
{$
var folder = HttpContext.Current.Request.Form [folder];
var fileName = HttpContext.Current.Request.Form [name ];
fileName = string.IsNullOrEmpty(fileName)?h ttpPostedFile.FileName:fileName;
//获取完整的文件路径
var fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath(〜/ Files /+文件夹),fileName);
//将上传的文件保存到UploadedFiles文件夹
httpPostedFile.SaveAs(fileSavePath);
$ b return ok(新的OkMessage {Message =File uploaded successfully,Path =/ Files /+ folder +/+ fileName});
返回BadRequest(File not uploaded);
$ / code>
请帮助我错在哪里以及如何达到这个目标替代改造?
此代码运行成功,感谢
Ion.with((github.com/koush/ion)rel =noreferrer> koush / getContext())
.load(POST,http://www.dgheating.com/api/jobDocuments/upload)
.setMultipartParameter(folder,LeadDocuments)
.setMultipartParameter(name,fileName)
.setMultipartFile(file,new File(imagePath))
.asJsonObject()
.setCallback(...)
所以,希望不会太晚,如果是的话 - 它可能帮助别人:)我的2美分关于这是一段时间后有相同的问题:
服务定义,使用 @部分
(根据您的服务器预期修改字段名称)
//单个图像MultiPart
@Multipart
@POST(user / imageupload)
Call< ResponseBody>上传(@Part(userfile)RequestBody文件,@Part(userid)RequestBody描述);
对于这个魔术,我将这两个部分都称为 RequestBody
,使用 MediaType.parse()
给它自己的类型,依靠 @Multipart
定义为请求本身,不需要 form-data
东西,对于多个文件和多个字段也是一样的:
private static final String IMG_JPEG =image / jpeg;
private static final String TXT_PLAIN =text / plain;
public void uploadImageMultipart(Uri uri,final CustomEventListener< String> listener)
{
RequestBody fileBody;
RequestBody textBody;
档案档案=新档案(uri.getPath());
呼叫< ResponseBody> requestCall;
fileBody = RequestBody.create(okhttp3.MediaType.parse(IMG_JPEG),file);
textBody = RequestBody.create(okhttp3.MediaType.parse(TXT_PLAIN),String.valueOf(SettingsManager.getUserID()));
requestCall = serviceCaller.upload(fileBody,textBody);
requestCall.enqueue(new Callback< ResponseBody>()
{
@Override
public void onResponse(Call< ResponseBody> call,retrofit2.Response< ResponseBody> rawResponse)
$
String response = rawResponse.body()。string();
//从这里开始显示....
listener .getResult(Got it);
}
catch(Exception e)
{
e.printStackTrace();
}
}
$ b $ @Override
public void onFailure(Call< ResponseBody> call,Throwable throwable)
{
}
});
$ b (我使用监听器将回调响应返回给应用程序(例如调用活动))。
这肯定会发送文件和文本字段,其他问题可能源自服务器端。
希望这有助于!
Read edit at bottom of the question for possible alternative solution until the solution is found.
This is a successful post file with two parameters using POSTMan. I am trying to do the same with retrofit but receive BadRequest.
PostMan Settings:
Chrome Network Post Details:
Now here is how I am doing this in Android but failing:
Retrofit Service Interface:
@Multipart
@POST("jobDocuments/upload")
Call<ResponseBody> upload(@Part("file") MultipartBody.Part file,@Part("folder") MultipartBody.Part folder,@Part("name") MultipartBody.Part name);
This is my @Background method to run the network request with above service generated
CustDataClient service =
ServiceGenerator.createService(CustDataClient.class);
File file = new File(fileUri.getPath());
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part fileData =
MultipartBody.Part.createFormData("file", fileName, requestFile);
MultipartBody.Part folder =
MultipartBody.Part.createFormData("folder", "LeadDocuments");
MultipartBody.Part name =
MultipartBody.Part.createFormData("name", fileName);
// finally, execute the request
Call<ResponseBody> call = service.upload(fileData,folder,name);
try {
Response<ResponseBody> rr = call.execute();
ResponseBody empJobDocsResult = rr.body();//Bad Request here :(
Log.v("Upload", "success");
} catch (Exception ex) {
Log.e("Upload error:", ex.getMessage());
}
Here is my Web Api Method:
[Route("upload")]
[HttpPost]
public IHttpActionResult Upload()
{
if (HttpContext.Current.Request.Files.AllKeys.Any())
{
// Get the uploaded image from the Files collection
var httpPostedFile = HttpContext.Current.Request.Files["file"];
if (httpPostedFile != null)
{
// Validate the uploaded image(optional)
var folder = HttpContext.Current.Request.Form["folder"];
var fileName = HttpContext.Current.Request.Form["name"];
fileName = string.IsNullOrEmpty(fileName) ? httpPostedFile.FileName : fileName;
// Get the complete file path
var fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Files/" + folder), fileName);
// Save the uploaded file to "UploadedFiles" folder
httpPostedFile.SaveAs(fileSavePath);
return Ok(new OkMessage { Message = "File uploaded successfully", Path = "/Files/" + folder + "/" + fileName });
}
}
return BadRequest("File not uploaded");
}
Please help where I am wrong and how to achieve this, is there any easy alternative to retrofit?
[Edit]
This code is working successfully, Thanks to koush/ion:
Ion.with(getContext())
.load("POST", "http://www.dgheating.com/api/jobDocuments/upload")
.setMultipartParameter("folder", "LeadDocuments")
.setMultipartParameter("name", fileName)
.setMultipartFile("file", new File(imagePath))
.asJsonObject()
.setCallback(...);
解决方案 So, hope it's no too late, and if so - it might help somebody else :) my 2 cents about this is after having the same problem a while back:
The service definition, using @Part
only (modify field names according to what your server expects)
//Single image MultiPart
@Multipart
@POST("user/imageupload")
Call<ResponseBody> upload(@Part("userfile") RequestBody file, @Part("userid") RequestBody description);
And for the magic trick, I refer to both parts just as RequestBody
, using the MediaType.parse()
to each one with it's own type, relying on the @Multipart
definition for the request itself, no need for form-data
stuff, the same works for multiple files, and multiple fields:
private static final String IMG_JPEG = "image/jpeg";
private static final String TXT_PLAIN = "text/plain";
public void uploadImageMultipart(Uri uri, final CustomEventListener<String> listener)
{
RequestBody fileBody;
RequestBody textBody;
File file = new File(uri.getPath());
Call<ResponseBody> requestCall;
fileBody = RequestBody.create(okhttp3.MediaType.parse(IMG_JPEG), file);
textBody = RequestBody.create(okhttp3.MediaType.parse(TXT_PLAIN), String.valueOf(SettingsManager.getUserID()));
requestCall = serviceCaller.upload(fileBody, textBody);
requestCall.enqueue(new Callback<ResponseBody>()
{
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> rawResponse)
{
try
{
String response = rawResponse.body().string();
//from here it's your show....
listener.getResult("Got it");
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable throwable)
{
}
});
}
(I use a listener to return the callback response to a different part of the app (e.g. a calling activity)).
This definitely sends the file/s and the text field, other problems would probably stem from the server side.
Hope this Helps!
这篇关于Retrofit 2不能上传带有两个额外单独字符串参数的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!