Retrofit 2不能上传带有两个额外单独字符串参数的文件 [英] Retrofit 2 can't upload a file with two additional separate string parameters

查看:1053
本文介绍了Retrofit 2不能上传带有两个额外单独字符串参数的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读编辑问题底部的可能替代解决方案,直到找到解决方案



是一个使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆