RestTemplate的使用和原理你都烂熟于胸了吗?【享学Spring MVC】 (2)

Form Data方式:我们用from表单提交的方式就是它;使用ajax(注意:这里指的是jQuery的ajax,而不是源生js的)默认的提交方式也是它~

在这里插入图片描述

request payload方式:多部分方式/json方式

在这里插入图片描述


在这里插入图片描述

这两种方式是通过Content-Type来区别的:若是application/x-www-form-urlencoded那就是formdata方式;若是application/json或者multipart/form-data等方式那就是request payload方式

jQuery在执行post请求时,默认会给你设置Content-Type为application/x-www-form-urlencoded,所以服务器能够正确解析。
若使用js原生的ajax,如果不显示的设置Content-Type,那么默认是text/plain,这时服务器就不知道怎么解析数据了,所以才只能通过获取原始数据流的方式来进行解析请求数据。(相信没人这么干吧~)

exchange和execute方法:

exchange方法:更通用的请求方法。它入参必须接受一个RequestEntity,从而可以设置请求的路径、头等等信息,最终全都是返回一个ResponseEntity(可以发送Get、Post、Put等所有请求)。
execute方法:最最最底层、通用的请求方法。

RequestCallback:用于操作请求头和body,在请求发出前执行;ResponseExtractor:解析/提取HTTP响应的数据,而且不需要担心异常和资源的关闭
RequestCallback.doWithRequest(ClientHttpRequest)说白了就是拿到ClientHttpRequest后对他进行继续处理~
RestTemplate的acceptHeaderRequestCallback、httpEntityCallback这些方法可以设置它~
---

HttpAccessor、InterceptingHttpAccessor

这两个抽象类不容忽视,HystrixCommand和Ribbon的逻辑都和它有关系(拦截器)。
HttpAccessor是个抽象基类,它定义要操作ClientHttpRequestFactory的公共属性,它一般不直接使用。

// @since 3.0 public abstract class HttpAccessor { // RestTemplate默认使用的客户端工厂:基于源生JDK private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); // 若要切换成三方库的底层组件,设置此方法便可 public void setRequestFactory(ClientHttpRequestFactory requestFactory) { this.requestFactory = requestFactory; } ... // get方法 // 供给子类非常方便的拿到一个ClientHttpRequest protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException { ClientHttpRequest request = getRequestFactory().createRequest(url, method); return request; } }

它的子类是:InterceptingHttpAccessor,也还是个抽象实现,主要是管理起了请求的拦截器们:ClientHttpRequestInterceptor。

InterceptingHttpAccessor // @since 3.0 // @see InterceptingClientHttpRequestFactory public abstract class InterceptingHttpAccessor extends HttpAccessor { // 装载需要作用在RestTemplate上的拦截器们~~~ private final List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>(); @Nullable private volatile ClientHttpRequestFactory interceptingRequestFactory; // 这里语意是set,所以是完全的替换掉(支持ordered排序哦~~~) public void setInterceptors(List<ClientHttpRequestInterceptor> interceptors) { if (this.interceptors != interceptors) { this.interceptors.clear(); this.interceptors.addAll(interceptors); AnnotationAwareOrderComparator.sort(this.interceptors); } } // 复写了父类的这个方法很有意思 // 意思为:若你调用者手动set进来了,那就以调用者设置的工厂为准 否则使用的是InterceptingClientHttpRequestFactory @Override public void setRequestFactory(ClientHttpRequestFactory requestFactory) { super.setRequestFactory(requestFactory); this.interceptingRequestFactory = null; } // 若配置了拦截器,那么默认就使用InterceptingClientHttpRequestFactory,而不再是SimpleClientHttpRequestFactory了~~~ @Override public ClientHttpRequestFactory getRequestFactory() { List<ClientHttpRequestInterceptor> interceptors = getInterceptors(); if (!CollectionUtils.isEmpty(interceptors)) { ClientHttpRequestFactory factory = this.interceptingRequestFactory; if (factory == null) { factory = new InterceptingClientHttpRequestFactory(super.getRequestFactory(), interceptors); this.interceptingRequestFactory = factory; } return factory; } else { return super.getRequestFactory(); } } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zggfjz.html