美文网首页
Volley源码学习8-Response、NetworkResp

Volley源码学习8-Response、NetworkResp

作者: 依然淳熙 | 来源:发表于2017-10-16 17:01 被阅读0次

    其实刚开始看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<String, List<String>>类型的响应头转化为 List<Header> 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<Header> 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<String, String> 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<Header> 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<String, String> 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.<Header>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<String, String> headers) {
            this(HttpURLConnection.HTTP_OK, data, headers, false, 0);
        }
    
        private NetworkResponse(int statusCode, byte[] data, Map<String, String> headers,
                List<Header> 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<String> 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 <code>errorCode != OK</code>. */
        public final VolleyError error;
    
    /** Returns a successful response containing the parsed result. */
        public static <T> Response<T> success(T result, Cache.Entry cacheEntry) {
            return new Response<T>(result, cacheEntry);
        }
        private Response(T result, Cache.Entry cacheEntry) {
            this.result = result;
            this.cacheEntry = cacheEntry;
            this.error = null;
        }
    

    这样就完成了转换。

    相关文章

      网友评论

          本文标题:Volley源码学习8-Response、NetworkResp

          本文链接:https://www.haomeiwen.com/subject/ftnkuxtx.html