Volley StringRequest和JSONObjectRequest的使用

Volley的参数传递:StringRequest,ImageRequest都可通过重写其父类Request的getHeaders(get请求方式)和getParams(post请求方式)传递参数的,而JsonRequest和JsonObjectRequest由于重写了getBody(),使得Request中的方法失效:

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

即JsonRequest中的getBody()方法变成这样:
  @Override
    public byte[] getBody() {
        try {
            return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET);
        } catch (UnsupportedEncodingException uee) {
            VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
                    mRequestBody, PROTOCOL_CHARSET);
            return null;
        }
    }


也就是说我们不再需要重写getParams()或getHeaders()来传递参数了,JsonRequest和JsonObjectRequest通过构造方法,自带有传递参数功能,JsonRequest参数是String类型的,我们可以直接用json或key=value形式,但JsonObjectRequest参数则是以JsonObject形式传入的,这就要求服务器必须支持json串型参数才行,若还想采用JsonObjectRequest并以key=value发给服务器,那么需要定义一个类继承JsonObjectRequest,重点重写getBodyContentType这个方法来实现了,详细写法如下:

public class MyJsonObjectRequest extends JsonRequest {  
  
    String stringRequest;  
  
    /** 
     * 这里的method必须是Method.POST,也就是必须带参数。 
     * 如果不想带参数,可以用JsonObjectRequest,给它构造参数传null。GET方式请求。 
     * @param stringRequest 格式应该是 "key1=value1&key2=value2" 
     */  
  
    public MyJsonObjectRequest(String url, String stringRequest,  
                             Response.Listener listener, Response.ErrorListener errorListener) {  
        super(Method.POST, url,stringRequest , listener, errorListener);  
        this.stringRequest = stringRequest;  
    }  
  
    @Override  
    public String getBodyContentType() {  
        return "application/x-www-form-urlencoded; charset=" + getParamsEncoding();  
    }  
  
    @Override  
    protected Response parseNetworkResponse(NetworkResponse response) {  
        try {  
            String jsonString = new String(response.data,  
                    HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));  
            return Response.success(new JSONObject(jsonString),  
                    HttpHeaderParser.parseCacheHeaders(response));  
        } catch (UnsupportedEncodingException e) {  
            return Response.error(new ParseError(e));  
        } catch (JSONException je) {  
            return Response.error(new ParseError(je));  
        }  
    }  


请求方法:
[java] view plain copy print?
private void jsonObjectRequestPostSuccess1(){  
        String url = "http://route.showapi.com/213-3";  
        Map map = DummyData.getDummyData();  
        String params = appendParameter(url,map);  
  
        MyJsonObjectRequest jsonObjectRequest = new MyJsonObjectRequest(url,params, new Response.Listener() {  
            @Override  
            public void onResponse(JSONObject response) {  
                responseText.setText(response.toString());  
            }  
        }, new Response.ErrorListener() {  
            @Override  
            public void onErrorResponse(VolleyError error) {  
                responseText.setText(error.getMessage());  
            }  
        });  
        mQueue.add(jsonObjectRequest);  
    }  
  
  
  
    private String appendParameter(String url,Map params){  
        Uri uri = Uri.parse(url);  
        Uri.Builder builder = uri.buildUpon();  
        for(Map.Entry entry:params.entrySet()){  
            builder.appendQueryParameter(entry.getKey(),entry.getValue());  
        }  
        return builder.build().getQuery();  
    }  


也并非一定要自定义一个JsonObjectRequest不可,如果了解Request的继承关系和参数的传递流程,直接使用JsonObjectRequest也是可以的。

private void jsonObjectRequestPostSuccess2(){  
    String url = "http://route.showapi.com/213-3";  
    Map params = DummyData.getDummyData();  
    final String mRequestBody = appendParameter(url,params);  
  
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,url,null, new Response.Listener() {  
        @Override  
        public void onResponse(JSONObject response) {  
            responseText.setText(response.toString());  
        }  
    }, new Response.ErrorListener() {  
        @Override  
        public void onErrorResponse(VolleyError error) {  
            responseText.setText(error.getMessage());  
        }  
    }){  
        @Override  
        public String getBodyContentType() {  
            return "application/x-www-form-urlencoded; charset=" + getParamsEncoding();  
        }  
  
        @Override  
        public byte[] getBody() {  
            try {  
                return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET);  
            } catch (UnsupportedEncodingException uee) {  
                VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",  
                        mRequestBody, PROTOCOL_CHARSET);  
                return null;  
            }  
        }  
    };  
    mQueue.add(jsonObjectRequest);  
}  
  
private String appendParameter(String url,Map params){  
    Uri uri = Uri.parse(url);  
    Uri.Builder builder = uri.buildUpon();  
    for(Map.Entry entry:params.entrySet()){  
        builder.appendQueryParameter(entry.getKey(),entry.getValue());  
    }  
    return builder.build().getQuery();  
}  
总结:

Volley.它的设计目标是进行数据量不大,但通信频繁的网络操作.
使用JsonObjectRequest 请求服务器,它的参数是以 json 串 的格式传输给服务器的,考虑服务器是否支持这种格式,可以在JsonRequest的PROTOCOL_CONTENT_TYPE中看到它传递参数的类型。如果服务器支持的是 http:...?key1=value1&key2=value2这种格式,也就是对应Request.java中的PROTOCOL_CONTENT_TYPE变量类型。就需要做一些改动,有两种方式来实现。第一种方式是定义一个类继承JsonObjectRequest,第二种直接使用JsonObjectRequest。原理是相同的,重点是重写匿名内部类的getBodyContentType这个方法。不能重写getParams这个方法类传参。

使用StringRequest 如果是带参数,或者Http Header,或者其他,可以重写它匿名内部类方法,如getParams(),getHeader()等等。
参考网址:http://blog.csdn.net/onlysnail/article/details/47905375



你可能感兴趣的:(请求)