RestTemplate详解 Springboot — 用更优雅的方式发HTTP请求( 三 )


RestTemplate详解 Springboot — 用更优雅的方式发HTTP请求

文章插图
代码中,MultiValueMap是Map的一个子类,它的一个key可以存储多个value,简单的看下这个接口:
public interface MultiValueMap<K, V> extends Map<K, List<V>> {...}为什么用MultiValueMap?因为HttpEntity接受的request类型是它 。
public HttpEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers){}我这里只展示它的一个construct,从它可以看到我们传入的map是请求体,headers是请求头 。为什么用HttpEntity是因为
restTemplate.postForEntity方法虽然表面上接收的request是@Nullable Object request类型,但是你追踪下去会发现,这个request是用HttpEntity来解析 。核心代码如下:
if (requestBody instanceof HttpEntity) { this.requestEntity = (HttpEntity<?>) requestBody;}else if (requestBody != null) { this.requestEntity = new HttpEntity<>(requestBody);}else { this.requestEntity = HttpEntity.EMPTY;}我曾尝试用map来传递参数,编译不会报错,但是执行不了,是无效的url request请求(400 ERROR) 。其实这样的请求方式已经满足post请求了,cookie也是属于header的一部分 。可以按需求设置请求头和请求体 。其它方法与之类似 。
4. 使用exchange指定调用方式
exchange()方法跟上面的getForObject()、getForEntity()、postForObject()、postForEntity()等方法不同之处在于它可以指定请求的HTTP类型 。

RestTemplate详解 Springboot — 用更优雅的方式发HTTP请求

文章插图
但是你会发现exchange的方法中似乎都有@Nullable HttpEntity<?> requestEntity这个参数,这就意味着我们至少要用HttpEntity来传递这个请求体,之前说过源码所以建议就使用HttpEntity提高性能 。
示例@Testpublic void rtExchangeTest() throws JSONException {RestTemplate restTemplate = new RestTemplate();String url = "http://xxx.top/notice/list";HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);JSONObject jsonObj = new JSONObject();jsonObj.put("start",1);jsonObj.put("page",5);HttpEntity<String> entity = new HttpEntity<>(jsonObj.toString(), headers);ResponseEntity<JSONObject> exchange = restTemplate.exchange(url,HttpMethod.GET, entity, JSONObject.class);System.out.println(exchange.getBody());}这次可以看到,我使用了JSONObject对象传入和返回 。
当然,HttpMethod方法还有很多,用法类似 。
5. excute()指定调用方式excute()的用法与exchange()大同小异了,它同样可以指定不同的HttpMethod,不同的是它返回的对象是响应体所映射成的对象<T>,而不是ResponseEntity<T> 。
需要强调的是,execute()方法是以上所有方法的底层调用 。随便看一个:
@Override @Nullable public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)throws RestClientException {RequestCallback requestCallback = httpEntityCallback(request, responseType);HttpMessageConverterExtractor<T> responseExtractor =new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables); }
【RestTemplate详解 Springboot — 用更优雅的方式发HTTP请求】


推荐阅读