Bootstrap

Volley直接设置POST包体

Volley直接设置POST包体

事件起源

由于现在帮别人做二次开发,就遇到有后台人员全部是天坑,都是拼音过了8级的人才。而且网络请求方式也是挺奇葩,并不是键值对的方式进行请求,而是一个JSON字符串放在POST包体中进行请求。


之前一直封装好的Volley帮助类放在这里来直接没法用了,然后就需要新增一个直接设置POST包体的请求方法。然而发现网上全部都是说的重写getParams方法来给Volley设置请求参数。那没法,我就只有硬着头皮来做我最不想做的事情了————看源代码。

从何下手?

因为所有人都说重写getParams方法,那么我们就先去看看这个getParams方法到底具体的做了些什么操作。
我用的是StringRequest这个类,然后点进去,看到是继承了Request这个类,代码如下:

public class StringRequest extends Request<String> {
    private final Listener<String> mListener;

    public StringRequest(int method, String url, Listener<String> listener,
            ErrorListener errorListener) {
        super(method, url, errorListener);
        mListener = listener;
    }

    public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
        this(Method.GET, url, listener, errorListener);
    }

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

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        String parsed;
        try {
            parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        } catch (UnsupportedEncodingException e) {
            parsed = new String(response.data);
        }
        return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
    }
}

显然这里面没有我们要找的getParams方法,那么继续往下面走,点进Request这个类。这个类里面代码很多了,搜索getParams,然后会找到在getBody方法里面对它进行了调用:

public byte[] getBody() throws AuthFailureError {
        Map<String, String> params = getParams();
        if (params != null && params.size() > 0) {
            return encodeParameters(params, getParamsEncoding());
        }
        return null;
    }

从这里的返回值里面看到另外的一个方法,encodeParameters,点过去:

private byte[] encodeParameters(Map<String, String> params, String paramsEncoding) {
        StringBuilder encodedParams = new StringBuilder();
        try {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
                encodedParams.append('=');
                encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));
                encodedParams.append('&');
            }
            return encodedParams.toString().getBytes(paramsEncoding);
        } catch (UnsupportedEncodingException uee) {
            throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
        }
    }

看到其实是在这里对map进行遍历,拼接成了字符串,之后再转换成的byte[]返回给getBody,最终成为了POST的请求包体。

如何修改?

现在需要再回到发起请求的地方,现在不再重写getParams这个方法了,我们需要重写的是getBody的方法:

            @Override
            public byte[] getBody() {
                try {
                    return body.getBytes(getParamsEncoding());
                } catch (UnsupportedEncodingException e) {
                    return null;
                }
            }

这里的body就是包体的字符串了,然后调用Volley中本身封装好的getParamsEncoding即可。

总结

这里实际上最后的操作非常简单,就是重写了另外一个方法,但是中间的过程则是需要在之后遇到问题的时候再次用得到的,谢谢各位看官,么么哒。

;