架构师学习--okhttp3责任链模式(包含请求封装和结果解析)

之前原理解析中说到,okHttp3使用了责任链模式添加了很多的拦截器,比如重试拦截器、请求头拦截器等等。有了这些拦截器,就可以把网络请求的不同部分交给各自拦截器实现,然后将拦截器处理的结果拼接成一个完整的请求实体,交给服务器。

一、拦截器接口 Interceptor2

为子链提供拦截方法intercept(),为管理类提供request()和response()方法。
在这里插入图片描述

二、责任链管理类 ChainManager2

在这里插入图片描述
实现了Chain接口,默认index为0,从第一个拦截器开始。

重写的两个方法如下:
在这里插入图片描述
注意这里的reques2是不断发生变化的,比如第一个拦截器处理完将信息放到request中,下一个拦截器也会更新它。最终所有的拦截器处理完成后,这里的request就保存了完整的请求信息。调用interceptor.intercept(next)后,就会触发第index个拦截器。

三、重试拦截器 RetryAndFollowUpInterceptor2

在这里插入图片描述
第一个拦截器,主要负责网络请求重试的。重试次数可以自定义。如果拿到请求结果就返回给调用者ChainManager2的response()方法返回。其中在chain.response()的时候,会调用下一个拦截器

四、请求头拦截器 BridgeInterceptor2

在这里插入图片描述
是不是看到这样,有点莫名其妙。其实完整的http或https请求就是通过拼接的形式,形成一条完整的请求字符串的。这里先分析下Get请求与Post请求的区别:

1、Get请求

(1)请求行
(2)请求属性集
在这里插入图片描述

2、Post请求

(1)请求行
(2)请求属性集
(3)请求体的长度
(4)请求的类型
在这里插入图片描述
**因此,代码中加入了POST请求的判断,针对该请求必须要加上请求体的长度和请求类型。**完成了请求头拦截器的处理,下一步交给服务器请求拦截器处理。

五、服务器请求拦截器 ConnectInterceptor2

这一块分为2个部分:

  1. 请求体的拼接
  2. 请求结果的解析
1、请求体的拼接

在这里插入图片描述
通过ParseSocket这个类,调用getAllHeader()方法,返回所有的拼接字符串。

2、getAllHeader()方法
	/**
     * 拼接所有的请求头部分
     *
     * @param request2
     * @return
     */
    public String getAllHeader(Request2 request2) {

        // TODO 获取当前请求的地址 /v3/weather/weatherInfo?city=110101&key=13cb58f5884f9749287abbead9c658f2
        String file = null;
        try {
            URL url = new URL(request2.getUrl2());
            file = url.getFile();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        StringBuffer sb = new StringBuffer();

        /**
         * TODO 拼接:
         * POST /v3/weather/weatherInfo?city=110101&key=13cb58f5884f9749287abbead9c658f2 HTTP/1.1
         */
        sb.append(request2.getMethod())
                .append(SPACE)
                .append(file)
                .append(SPACE)
                .append(HTTP_VERSION)
                .append(BREAK);
        /**
         * TODO 拼接:
         * Content-Length: 0
         * Host: restapi.amap.com
         * Content-Type: application/json
         */

        Map<String, String> headerList = request2.getHeaderList();
        Set<Map.Entry<String, String>> entries = headerList.entrySet();

        for (Map.Entry<String, String> entry : entries) {
            sb.append(entry.getKey())
                    .append(":")
                    .append(SPACE)
                    .append(entry.getValue())
                    .append(BREAK);
        }
        sb.append(BREAK);

        /**
         * TODO 拼接:
         * post请求拼接请求体:
         * city=110101&key=13cb58f5884f9749287abbead9c658f2
         */
        if ("POST".equalsIgnoreCase(request2.getMethod())) {
            sb.append(request2.getRequestBody2().getBody())
                    .append(BREAK);
        }

        return sb.toString();

    }

按照服务器标准请求的方式,拼接返回,注意空格和换行也要加上。 标准格式如下:
在这里插入图片描述

3、发送请求

(1)连接socket
这里注意,HTTP和HTTPS实例化socket的方式是不同的,处理方式如下:
在这里插入图片描述
(2)发送请求
在这里插入图片描述
不要忘记调用flush()方法。

4、处理返回结果

在这里插入图片描述
首先看一下,服务器完整的返回信息:
在这里插入图片描述
第一行是返回的请求状态,在解析流的时候只要解析到空行,那么下一行一定是返回的结果,这是规范。

六、使用拦截器

在这里插入图片描述
默认实现执行第一个重试拦截器,经过拦截器处理会将结果返回到这里。

完整代码:

代码传送门

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值