使用VolleyPlus的MultiPartRequest - “响应代码411长度要求”

时间:2015-03-11 12:49:43

标签: android android-volley

我正在尝试使用DWorkS/VolleyPlus制作MultiPartRequest

我搜索了GitHub存储库及其示例代码,但我找不到使用此类的示例。

当我提出请求时,我收到了411响应代码。我的理解是,当服务器拒绝接受没有内容长度标头的消息时,它会作为响应发送。我该如何提供这个?

以下是显示错误的LogCat的相关部分,以及我的方法。

查看MultiPartRequest的代码,它有一个名为isFixedStreamingMode的字段。对于连接,此名称与setFixedLengthStreamingMode类似,但我无法在代码中查看它的使用位置。它也是boolean而不是int,所以我无法提供它的长度。有谁知道这个领域是什么?

是否有人成功使用过此库中的MultiPartRequest?任何建议或例子将不胜感激。

我目前正在使用此库中的StringRequest类成功制作POST,GET和PUT方法。

logcat的

03-11 22:17:15.388  25236-25236/au.com.xxx.yyy D/MainActivity﹕ postMyItem: http://yyy.zzz.com.au/api/v1/my_item
03-11 22:17:15.507  25236-25309/au.com.xxx.yyy E/Volley﹕ [5861] BasicNetwork.performRequest: Unexpected response code 411 for http://yyy.zzz.com.au/api/v1/my_item
03-11 22:17:15.508  25236-25236/au.com.xxx.yyy D/MainActivity﹕ error response: <html>
    <head><title>411 Length Required</title></head>
    <body bgcolor="white">
    <center><h1>411 Length Required</h1></center>
    <hr><center>nginx/1.1.19</center>
    </body>
    </html>
03-11 22:17:15.508  25236-25236/au.com.xxx.yyy D/MainActivity﹕ Volley Error: com.android.volley.error.VolleyError

方式

public void postMyItem(final MyItem myItem) {

    String url = getString(R.string.url__server_api) + getString(R.string.post__my_item);

    MultiPartRequest request = new MultiPartRequest(Request.Method.POST, url, 
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Volley POST MyItem response: " + response);
                },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d(TAG, "Volley Error: " + error);
                try {
                    String response = new String(error.networkResponse.data, "utf-8");
                    Log.d(TAG, "error response: " + response);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }                        
            }
        })
    {
        @Override
        protected Response parseNetworkResponse(NetworkResponse networkResponse) {
            return null;
        }

        @Override
        public Map<String, String> getHeaders() throws com.android.volley.error.AuthFailureError {
            Map<String, String> map = new HashMap<>();
            map.put(getString(R.string.header_field__access_token), mAccess_token);
            return map;
        }
    };

    if (myItem.name != null) {
        request.addMultipartParam("name", "multipart/mixed", myItem.name);
    }

    if (myItem.quantity != null) {
        request.addMultipartParam("quantity", "multipart/mixed", myItem.quantity);
    }

    ...

    //TODO: request.addFile(name, filePath)

    VolleySingleton.getInstance(this).addToRequestQueue(request);
}

2 个答案:

答案 0 :(得分:1)

因此,在上传图像setFixedStreamingMode之前,服务器可能需要告知内容长度。示例代码位于

之下
SimpleMultipartRequest request = new SimpleMultipartRequest(Method.POST, apiUrl, mListener, mErrorListener);
request.addFile("photo", image_path);
RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());
mRequestQueue.add(request);
mRequestQueue.setFixedStreamingMode(true);
mRequestQueue.start();

答案 1 :(得分:0)

您可以在截击请求中使用MultipartEntitiy在您的请求正文中添加多部分数据,方法是重写getBody方法,如下所示:

public class MultipartRequest extends Request<String> {

private MultipartEntity entity = new MultipartEntity();
private static final String FILE_PART_NAME = "file";
private static final String STRING_PART_NAME = "text";
private static final String SELFIE_IMAGE = "selfieImage";
private static final String SELFIE_CAPTION = "cap";

private final Response.Listener<String> mListener;
private final File mFilePart;
private final String mStringPart;

public MultipartRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, File file, String stringPart)
{
    super(Method.POST, url, errorListener);

    mListener = listener;
    mFilePart = file;
    mStringPart = stringPart;
    buildMultipartEntity();
}

private void buildMultipartEntity()
{  System.out.println("buildMultipartEntity");

    entity.addPart(SELFIE_IMAGE, new FileBody(mFilePart));
    try
    {
        entity.addPart(SELFIE_CAPTION, new StringBody(mStringPart));
    }
    catch (UnsupportedEncodingException e)
    {
        VolleyLog.e("UnsupportedEncodingException");
    }
}

@Override
public String getBodyContentType()

{  System.out.println("getBodyContentType");
    return entity.getContentType().getValue();
}

@Override
public byte[] getBody() throws AuthFailureError{
    System.out.println("getBody");

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try
    {
        entity.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
protected void deliverResponse(String response)
{
    mListener.onResponse(response);
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String, String> headers = super.getHeaders();
    System.out.println("getHeaders");

    if (headers == null
            || headers.equals(Collections.emptyMap())) {
        headers = new HashMap<String, String>();
    }

    AppController.getInstance().addSessionCookie(headers);

    return headers;

}

}