【问题标题】:Volley failing multipart form data requestVolley 失败的多部分表单数据请求
【发布时间】:2015-04-13 12:41:56
【问题描述】:

我正在尝试将多部分数据发送到服务器,该数据还包括一些图像。 所以我以这种方式扩展了Request

public class MultipartImageRequest extends Request<String> {

private MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();

private static final String STRING_PART_NAME = "text";

private final Response.Listener<String> mListener;
private final ArrayList<Bitmap> mFiles = new ArrayList<>();
private HashMap<String, String> mParams = new HashMap<>();

public MultipartImageRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, ArrayList<Bitmap> files, HashMap<String, String> params)
{
    super(Method.POST, url, errorListener);

    mListener = listener;
    mFiles.addAll(files);
    mParams = params;

}

private void buildMultipartEntity()
{

    int i = 0;
    for(Bitmap image : mFiles) {

        /*Compress bitmap*/
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 50, bos);

        entityBuilder.addPart("image_" + i, new ByteArrayBody(bos.toByteArray(), "image_" + i));
        i++;

    }


    StringBuilder paramsBuilder = new StringBuilder();
    Iterator<Map.Entry<String, String>> paramIterator = mParams.entrySet().iterator();
    while (paramIterator.hasNext()) {

        Map.Entry<String,String> entry = paramIterator.next();
       entityBuilder.addPart(entry.getKey(), new StringBody(entry.getValue(), ContentType.DEFAULT_TEXT));

    }




}

@Override
public String getBodyContentType()
{
    return "multipart/form-data; charset=utf-8";
}

@Override
public byte[] getBody() throws AuthFailureError
{

    buildMultipartEntity();

    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    try
    {
        entityBuilder.build().writeTo(bos);
    }
    catch (IOException e)
    {
        VolleyLog.e("IOException writing to ByteArrayOutputStream");
    }
    return bos.toByteArray();
}

@Override
protected Response<String> parseNetworkResponse(NetworkResponse response)
{
    return Response.success("Uploaded", getCacheEntry());
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String,String> params = new HashMap<String, String>();
    params.put("Content-Type","multipart/form-data; charset=utf-8");
    return params;
}

@Override
protected void deliverResponse(String response)
{
    mListener.onResponse(response);
}
}

问题是,如果我设置为内容类型application/json,它可以工作并将数据发送到服务器,但显然服务器给了我一个错误400,因为它期待一个多部分请求,而不是如果我设置内容类型为multipart/form-data; charset=utf-8,就像上面的代码Volley 一样,只是不发送请求并给我一个错误500。 我正在使用RequestBin 检查我的数据,它证实了我上面所说的。 此外,我正在使用 Rest Client,请求正在使用它,并且也在 iphone 上。

【问题讨论】:

    标签: android android-volley multipartform-data


    【解决方案1】:

    我自己找到了解决方案,给请求传递一个边界很重要,否则服务器将无法获取我们的参数。 可以替换此代码:

    public MultipartImageRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, ArrayList<Bitmap> files, HashMap<String, String> params)
    {
        super(Method.POST, url, errorListener);
    
        mListener = listener;
        mFiles.addAll(files);
        mParams = params;
    
    }
    

    用这个:

    public MultipartImageRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, ArrayList<Bitmap> files, HashMap<String, String> params)
    {
        super(Method.POST, url, errorListener);
    
        mListener = listener;
        mFiles.addAll(files);
        mParams = params;
        entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        entityBuilder.setBoundary(BOUNDARY);
    }
    

    记得在Content-Type中设置边界字符串:

    @Override
    public String getBodyContentType()
    {
        return "multipart/form-data; boundary=" + BOUNDARY + "; charset=utf-8";
    }
    
    
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String,String> params = new HashMap<String, String>();
    
        params.put("Content-Type","multipart/form-data; boundary=" + BOUNDARY + "; charset=utf-8");
        return params;
    }
    

    【讨论】:

    • @AmitKumarKannaujiya 你可以设置任何你想要的,你的边界可能是“blablabla”只是一个任意名称
    • 服务器人需要知道边界吗?
    • 不需要,因为您在标题中指定了它。
    • 你能检查一下这个问题stackoverflow.com/questions/29605623/… 是不是和你一样还是你有什么想法?
    • @AmitKumarKannaujiya 我错了还是你只是链接了这个讨论?
    猜你喜欢
    • 2013-04-27
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2014-09-21
    • 2019-06-10
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多