Volley源码学习8-Response、NetworkResponse、HttpResponse类

其实刚开始看volley代码的时候看到这三个类也不知道有啥区别,有点懵。先来看一看Http的响应报文:

HTTP的响应报文由状态行、消息报头、空行、响应正文组成。响应报头后面会讲到,响应正文是服务器返回的资源的内容,先来看看状态行。

状态行

1、状态行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
例:HTTP/1.1 200 OK
其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
1.100~199:指示信息,表示请求已接收,继续处理
2.200~299:请求成功,表示请求已被成功接收、理解、接受
3.300~399:重定向,要完成请求必须进行更进一步的操作
4.400~499:客户端错误,请求有语法错误或请求无法实现
5.500~599:服务器端错误,服务器未能实现合法的请求
常见的状态码如下:
1.200 OK:客户端请求成功
2.400 Bad Request:客户端请求有语法错误,不能被服务器所理解
3.401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
4.403 Forbidden:服务器收到请求,但是拒绝提供服务
5.500 Internal Server Error:服务器发生不可预期的错误
6.503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常
在volley的HurlStack通过HttpURLConnection访问网络,首先返回的是HttpResponse对象,代码如下:

if (!hasResponseBody(request.getMethod(), responseCode)) {
            return new HttpResponse(responseCode, convertHeaders(connection.getHeaderFields()));
        }

  return new HttpResponse(responseCode, convertHeaders(connection.getHeaderFields()),
                connection.getContentLength(), inputStreamFromConnection(connection));

根据请求方式和响应值来判断是否包含一个body也就是实体内容。convertHeaders()Map>类型的响应头转化为 List

HttpResponse的构造方法如下:

 /**
     * Construct a new HttpResponse.
     *
     * @param statusCode the HTTP status code of the response
     * @param headers the response headers
     * @param contentLength the length of the response content. Ignored if there is no content.
     * @param content an {@link InputStream} of the response content. May be null to indicate that
     *     the response has no content.
     */
    public HttpResponse(
            int statusCode, List
headers, int contentLength, InputStream content) { mStatusCode = statusCode; mHeaders = headers; mContentLength = contentLength; mContent = content; }

成员变量是什么注释说的很清楚~。将HttpResponse返回到BasicNetwork之后,根据返回状态码进行情况判断创建不同的NetworkResponse对象返回到NetworkDispatcher。

  return new NetworkResponse(statusCode, responseContents, false,
                        SystemClock.elapsedRealtime() - requestStart, responseHeaders);

上面这种返回是响应值为200时候的。NetworkResponse有好几个重载的构造方法如下:

/**
     * Creates a new network response.
     * @param statusCode the HTTP status code
     * @param data Response body
     * @param headers Headers returned with this response, or null for none
     * @param notModified True if the server returned a 304 and the data was already in cache
     * @param networkTimeMs Round-trip network time to receive network response
     * @deprecated see {@link #NetworkResponse(int, byte[], boolean, long, List)}. This constructor
     *             cannot handle server responses containing multiple headers with the same name.
     *             This constructor may be removed in a future release of Volley.
     */
    @Deprecated
    public NetworkResponse(int statusCode, byte[] data, Map headers,
            boolean notModified, long networkTimeMs) {
        this(statusCode, data, headers, toAllHeaderList(headers), notModified, networkTimeMs);
    }

    /**
     * Creates a new network response.
     * @param statusCode the HTTP status code
     * @param data Response body
     * @param notModified True if the server returned a 304 and the data was already in cache
     * @param networkTimeMs Round-trip network time to receive network response
     * @param allHeaders All headers returned with this response, or null for none
     */
    public NetworkResponse(int statusCode, byte[] data, boolean notModified, long networkTimeMs,
            List
allHeaders) { this(statusCode, data, toHeaderMap(allHeaders), allHeaders, notModified, networkTimeMs); } /** * Creates a new network response. * @param statusCode the HTTP status code * @param data Response body * @param headers Headers returned with this response, or null for none * @param notModified True if the server returned a 304 and the data was already in cache * @deprecated see {@link #NetworkResponse(int, byte[], boolean, long, List)}. This constructor * cannot handle server responses containing multiple headers with the same name. * This constructor may be removed in a future release of Volley. */ @Deprecated public NetworkResponse(int statusCode, byte[] data, Map headers, boolean notModified) { this(statusCode, data, headers, notModified, 0); } /** * Creates a new network response for an OK response with no headers. * @param data Response body */ public NetworkResponse(byte[] data) { this(HttpURLConnection.HTTP_OK, data, false, 0, Collections.
emptyList()); } /** * Creates a new network response for an OK response. * @param data Response body * @param headers Headers returned with this response, or null for none * @deprecated see {@link #NetworkResponse(int, byte[], boolean, long, List)}. This constructor * cannot handle server responses containing multiple headers with the same name. * This constructor may be removed in a future release of Volley. */ @Deprecated public NetworkResponse(byte[] data, Map headers) { this(HttpURLConnection.HTTP_OK, data, headers, false, 0); } private NetworkResponse(int statusCode, byte[] data, Map headers, List
allHeaders, boolean notModified, long networkTimeMs) { this.statusCode = statusCode; this.data = data; this.headers = headers; if (allHeaders == null) { this.allHeaders = null; } else { this.allHeaders = Collections.unmodifiableList(allHeaders); //作用返回一个只读的集合 } this.notModified = notModified; this.networkTimeMs = networkTimeMs; }

到NetworkResponse这里 ,已经有了响应状态,响应内容,响应头等。返回到NetworkDispatcher之后,又调用Request的parseNetworkResponse方法将NetworkResponse转化为Response。parseNetworkResponse是一个抽象方法,StringRequest里实现如下:

 @Override
    protected Response parseNetworkResponse(NetworkResponse response) {
        String parsed;
        try {
            //将byte[]数组根据指定编码转化为String
            parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        } catch (UnsupportedEncodingException e) {
            parsed = new String(response.data);
        }
        //HttpHeaderParser.parseCacheHeaders(response) 根据返回值header是否缓存进行缓存。
        return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
    }

通过parseNetworkResponse转化为Response对象。代码如下:

/** Parsed response, or null in the case of error. */
    public final T result;

    /** Cache metadata for this response, or null in the case of error. */
    public final Cache.Entry cacheEntry;

    /** Detailed error information if errorCode != OK. */
    public final VolleyError error;

/** Returns a successful response containing the parsed result. */
    public static  Response success(T result, Cache.Entry cacheEntry) {
        return new Response(result, cacheEntry);
    }
    private Response(T result, Cache.Entry cacheEntry) {
        this.result = result;
        this.cacheEntry = cacheEntry;
        this.error = null;
    }

这样就完成了转换。

你可能感兴趣的:(Volley源码学习8-Response、NetworkResponse、HttpResponse类)