排球失败的多部分表单数据请求

时间:2015-04-13 12:41:57

标签: android android-volley multipartform-data

我正在尝试将多部分数据发送到服务器,此数据还包括一些图像。 所以我以这种方式扩展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客户端,请求正在使用它和在iphone上。

1 个答案:

答案 0 :(得分:0)

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

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;
}