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

接下来更重要的便是它实现的接口方法了,我抽出一些关键点进行描述说明:

RestTemplate: @Override @Nullable public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException { //1、new AcceptHeaderRequestCallback(responseType) 它能在发送请求的之前这样一件事: // request.getHeaders().setAccept(allSupportedMediaTypes) RequestCallback requestCallback = acceptHeaderRequestCallback(responseType); HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger); // 最终调用的是execute方法,此时URL是个字符串 // responseExtractor返回值提取器使用的是消息转换器去读取body哒~ // 返回值就是返回的body本身(不含有返回的响应头等等信息~) return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables); } // 它返回的是ResponseEntity,不会返回null的 最终调用的依旧是execute方法 // 此时候用的就不是消息转换器的提取器了,而是内部类`ResponseEntityResponseExtractor`(底层还是依赖消息转换器) // 但是这个提取器,提取出来的可都是ResponseEntity<T>实例~ @Override public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException { RequestCallback requestCallback = acceptHeaderRequestCallback(responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return nonNull(execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables)); } // HEAD请求:很简单,使用的提取器就是headersExtractor,从返回值里把响应header拿出来即可 @Override public HttpHeaders headForHeaders(String url, Object... uriVariables) throws RestClientException { return nonNull(execute(url, HttpMethod.HEAD, null, headersExtractor(), uriVariables)); } // POST请求 @Override @Nullable public URI postForLocation(String url, @Nullable Object request, Object... uriVariables) throws RestClientException { // 1、HttpEntityRequestCallback 适配:把request适配成一个HttpEntity // 然后执行前,通过消息转换器把头信息、body信息等等都write进去 RequestCallback requestCallback = httpEntityCallback(request); // 因为需要拿到URI,所以此处使用headersExtractor提取器先拿到响应的header即可~~~ HttpHeaders headers = execute(url, HttpMethod.POST, requestCallback, headersExtractor(), uriVariables); return (headers != null ? headers.getLocation() : null); } // 除了httpEntityCallback()不一样,其余和get请求一样 @Override @Nullable public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException { RequestCallback requestCallback = httpEntityCallback(request, responseType); HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger); return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables); } // PUT请求:因为没有返回值,所以不需要返回值提取器。所以,非常的简单~~~ @Override public void put(String url, @Nullable Object request, Object... uriVariables) throws RestClientException { RequestCallback requestCallback = httpEntityCallback(request); execute(url, HttpMethod.PUT, requestCallback, null, uriVariables); } // DELETE请求:也是木有返回值的。 // 并且请注意:DELETE请求这里可都是不能接收body的,不能给请求设置请求体的 // (虽然可能底层httpCLient支持,但这里不支持,请遵守规范) @Override public void delete(String url, Object... uriVariables) throws RestClientException { execute(url, HttpMethod.DELETE, null, null, uriVariables); } // OPTIONS请求:和HEAD请求的处理逻辑几乎一样 @Override public Set<HttpMethod> optionsForAllow(String url, Object... uriVariables) throws RestClientException { ResponseExtractor<HttpHeaders> headersExtractor = headersExtractor(); HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, headersExtractor, uriVariables); return (headers != null ? headers.getAllow() : Collections.emptySet()); }

所有方法大体执行逻辑一致,都是和RequestCallback、responseExtractor等有关,且最终都是委托给了最为底层的execute()方法去执行。

你是否疑问:它提供的put方法返回值都是void,若我put请求就有返回值肿么办呢?那么接下来就介绍更为通用的一个方法:exchange()

RestTemplate: @Override public <T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException { // 把请求体适配为HttpEntity RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType); // 消息提取器使用ResponseEntityResponseExtractor ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); // 从上两个部分就能看到:exchange方法的入参、出参都是非常通用的~~~ return nonNull(execute(url, method, requestCallback, responseExtractor, uriVariables)); } // ParameterizedTypeReference参数化类型,用于处理泛型 // 上面的responseType就是个Class。这里是个参数化类型~~~~~ @Override public <T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType, Object... uriVariables) throws RestClientException { Type type = responseType.getType(); RequestCallback requestCallback = httpEntityCallback(requestEntity, type); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(type); return nonNull(execute(url, method, requestCallback, responseExtractor, uriVariables)); } // 这个方法就非常精简了,让调用者自己去构造RequestEntity,里面是包含了请求的URL和方法等信息的 @Override public <T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, Class<T> responseType) throws RestClientException { RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return nonNull(doExecute(requestEntity.getUrl(), requestEntity.getMethod(), requestCallback, responseExtractor)); }

exchange所有方法使用的都是HttpEntity和ResponseEntity代表请求实体和响应实体,足以见到它设计的通用性。

在Spring3.2后提供了ParameterizedTypeReference来处理参数化类型---> 主要是为了处理List等的泛型

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

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