android - Volley 失败的多部分表单数据请求

标签 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 Client 并且请求正在使用它以及在 iphone 上工作。

最佳答案

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

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

关于android - Volley 失败的多部分表单数据请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29605623/

相关文章:

java - 安卓工作室 :error: illegal character: '\u2028'

GWT客户端: sending a file with multipart/form-data post request

Android GPS在计算距离的精度问题

java - 强制魔法常数

Android Volley MalformedURLException 错误的 URL

java - Android 应用程序与服务器连接速度慢

java - 在 post 请求中作为 JSON 字符串传递的 FormDataParam 对象未正确反序列化

java - 重命名多部分文件的原始文件名

android - 如何以及在何处关闭()我的数据库以停止获取 E/SQLiteLog : (283)

android - 如何找到运行 64 位操作系统的 Android 手机进行软件测试?