内容简介:This is the last interceptor in the chain. It makes a network call to the server. 这是链中最后一个拦截器,它向服务器发起了一次网络访问请求服务拦截器,负责向服务器发送请求数据、从服务器读取响应数据未完待续
This is the last interceptor in the chain. It makes a network call to the server. 这是链中最后一个拦截器,它向服务器发起了一次网络访问
请求服务拦截器,负责向服务器发送请求数据、从服务器读取响应数据
源码解析
@Override public Response intercept(Chain chain) throws IOException { RealInterceptorChain realChain = (RealInterceptorChain) chain; HttpCodec httpCodec = realChain.httpStream(); StreamAllocation streamAllocation = realChain.streamAllocation(); RealConnection connection = (RealConnection) realChain.connection(); Request request = realChain.request(); long sentRequestMillis = System.currentTimeMillis(); // 整理请求头并写入 httpCodec.writeRequestHeaders(request); Response.Builder responseBuilder = null; // 检查是否为有 body 的请求方法 if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) { // If there is a "Expect: 100-continue" header on the request, wait for a "HTTP/1.1 100 // Continue" response before transmitting the request body. If we do not get that, return what // we did get (such as a 4xx response) without ever transmitting the request body. // 如果有 Expect: 100-continue在请求头中,那么要等服务器的响应。100-continue协议需要在post数据前, 征询服务器情况,看服务器是否处理POST的数据 if ("100-continue".equalsIgnoreCase(request.header("Expect"))) { //发送100-continue的请求 httpCodec.flushRequest(); //如果有中间级的响应,返回null responseBuilder = httpCodec.readResponseHeaders(true); } if (responseBuilder == null) { // Write the request body if the "Expect: 100-continue" expectation was met. // 写入请求体 Sink requestBodyOut = httpCodec.createRequestBody(request, request.body().contentLength()); BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut); request.body().writeTo(bufferedRequestBody); bufferedRequestBody.close(); } else if (!connection.isMultiplexed()) { // If the "Expect: 100-continue" expectation wasn't met, prevent the HTTP/1 connection from // being reused. Otherwise we're still obligated to transmit the request body to leave the // connection in a consistent state. streamAllocation.noNewStreams(); } } //发送最终的请求 httpCodec.finishRequest(); // 得到响应头 if (responseBuilder == null) { responseBuilder = httpCodec.readResponseHeaders(false); } Response response = responseBuilder .request(request) .handshake(streamAllocation.connection().handshake()) .sentRequestAtMillis(sentRequestMillis) .receivedResponseAtMillis(System.currentTimeMillis()) .build(); int code = response.code(); // 如果为 web socket 且状态码是 101 ,那么 body 为空 if (forWebSocket && code == 101) { // Connection is upgrading, but we need to ensure interceptors see a non-null response body. response = response.newBuilder() .body(Util.EMPTY_RESPONSE) .build(); } else { response = response.newBuilder() .body(httpCodec.openResponseBody(response)) .build(); } // 如果请求头中有 close 那么断开连接 if ("close".equalsIgnoreCase(response.request().header("Connection")) || "close".equalsIgnoreCase(response.header("Connection"))) { streamAllocation.noNewStreams(); } // 抛出协议异常 if ((code == 204 || code == 205) && response.body().contentLength() > 0) { throw new ProtocolException( "HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength()); } return response; } 复制代码
未完待续
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Struts2 源码分析-----拦截器源码解析 --- ParametersInterceptor
- Spring MVC 从源码分析到实践如何动态添加拦截器
- 再谈from属性EncType与axios分装—axios拦截器实现-源码浅析
- 前端架构之vue+axios 前端实现登录拦截(路由拦截、http拦截)
- react离开页面,自定义弹框拦截,路由拦截
- Springboot整合Hibernate拦截器时无法向拦截器注入Bean
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
DIV+CSS网站布局从入门到精通
2011-1 / 58.00元
《DIV+CSS网站布局从入门到精通》介绍了商业类型的网页设计,以及目前流行的div+CSS标准布局方法和实战技法。通过十个经典案例,分别从不同类型网站的布局风格以及实现方法来讲解div+CSS网页布局和制作方法。全书系统地讲解了CSS样式的基础理论和实际运用技术,并结合实例来讲解层叠样式表与层布局相结合制作网页的方法。在实例制作过程中除了介绍CSS样式设计各方面的知识外,还结合实际网页制作中可能......一起来看看 《DIV+CSS网站布局从入门到精通》 这本书的介绍吧!