Volley源码分析(二)-Volley中的Request类

Volley的简单介绍http://blog.csdn.net/chengshuyuan_uestc/article/details/51755189
Volley源码解析(一)Volley中乱码问题及解决方案http://blog.csdn.net/chengshuyuan_uestc/article/details/51755191
Volley源码分析(二)-Volley中的Request类http://blog.csdn.net/chengshuyuan_uestc/article/details/51755197
Volley源码解析(三)网络请求流程http://blog.csdn.net/chengshuyuan_uestc/article/details/51755201

Request类和Response类

刚才我们分析了请求String发生乱码的原因与解决方案,是因为如果服务器在http响应Response中没有设定编码方式charset,就会使用默认的ISO-8859-1编码方案。更进一步,我们分析一下Request类,看一下使用Volley进行http请求的。

http请求报文分为三个部分
- 请求行 实体行包括请求的方法、请求的url地址、请求的协议版本号
- 首部行 首部行包括四个部分 主机地址、 Connection、浏览器、语言
- 实体 get方法请求时实体为空,post方法时,实体中存放请求参数

典型的HTTP请求报文:
```
GET /somedir/index.html HTTP/1.1
HOST : www.baidu.com
Connection : close
user-agent : Mozilla/5/0
Agent-language : fr
实体
```

在Volley中是怎么实现的呢?我们以StringRequest来分析

在实例化StringRequest类时,出入了参数method、url、listener、ErrorListener,在StringRequest的构造函数中直接调用了父类Request的构造函数。即在构造函数中添加了http请求报文中的url,请求方法(Request类中显示Volley有8种方法,包括GET\POST\PUT\DELETE\HEAD\OPTIONS\TRACE\PATCH)。

如果是post方法,那么参数是放在http请求保温的实体中,这些参数是怎么传入的呢?

在HrulStack类中使用HttpUrlConnection来进行http请求的时候。

1 如果请求的方法为DEPRECATED_GET_OR_POST,

byte[] postBody = request.getPostBody();

可以看到http请求内容由Request类的getPostBody()提供,我们看一下这个函数的实现。

 @Deprecated
    public byte[] getPostBody() throws AuthFailureError {
        // Note: For compatibility with legacy clients of volley, this implementation must remain
        // here instead of simply calling the getBody() function because this function must
        // call getPostParams() and getPostParamsEncoding() since legacy clients would have
        // overridden these two member functions for POST requests.
        Map<String, String> postParams = getPostParams();
        if (postParams != null && postParams.size() > 0) {
            return encodeParameters(postParams, getPostParamsEncoding());
        }
        return null;
    }

postParms是一个Map,通过getPostParams()函数得到,继续查看getPostParams()函数,getPostParms()方法只有一句,就是调用getParams(),这个函数我们好熟悉,不就是我们在进行post方法进行网络请求时需要重写的方法,在该方法中用map的方法加入参数??

在得到postParams之后,如果postParms不为空,需要encodeParameters()处理一下,以一定的格式返回。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);
        }
    }

2 当然如果是GET方法的话

参数直接放在url中,就不需要这些过程了。

3 如果是POST方法呢?

如果是post方法, 则调用了ddBodyIfExists(connection, request)方法,我们看一下这个方法的实现。

//HrulStack类
private static void addBodyIfExists(HttpURLConnection connection, Request<?> request)
            throws IOException, AuthFailureError {
        byte[] body = request.getBody();
        if (body != null) {
            connection.setDoOutput(true);
            connection.addRequestProperty(HEADER_CONTENT_TYPE, request.getBodyContentType());
            DataOutputStream out = new DataOutputStream(connection.getOutputStream());
            out.write(body);
            out.close();
        }
    }

在函数内的第一行我们就看到通过调用Request类的getBody()方法来获得http请求的body。我们看一下Request类中的getBody()方法。

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

水落石出,同样是通过我们复写的getParams()方法后去参数后encodeParameters()方法进行转换成byte[]格式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值