笔者在两年前写过一篇RestTemplate使用相关的文章,地址: springboot中使用RestTemplate调用web服务小结
。
文章写作时SpringBoot版本尚在1.x徘徊,随着SpringBoot版本升级,有些用法在2.x版本中已经不适用。恰逢最近又用到了RestTemplate进行HTTP接口对接,
因此写作本文对最新的使用方法进行小结,方便后续参考,也希望能够帮到读者更好的使用RestTemplate在2.x的SpringBoot中进行HTTP接口的调用。
对于Get方式请求,2.x与1.x是兼容的,因此可以直接阅读上文中提到的链接,本文就不再重复赘述。
配置RestTemplate
首先需要配置RestTemplate,这是使用它的必要条件。
在项目中引入web依赖,maven坐标如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.1.3.RELEASE</version> </dependency>
只需要这个依赖即可。接着在项目中添加一个配置类,引入RestTemplate的bean定义,你可以直接引入下面的类。
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory){ return new RestTemplate(factory); } @Bean public ClientHttpRequestFactory simpleClientHttpRequestFactory(){ SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); /**读超时单位为ms*/ factory.setReadTimeout(10000); /**连接超时单位为ms*/ factory.setConnectTimeout(10000); return factory; } }
这里,我指定读取超时时间和连接超时时间为10s,读者朋友可以根据自己的具体情况灵活配置。
POST请求之表单提交
使用POST请求方式最常见的就是表单提交,更加专业的说法就是:content-type为 application/x-www-form-urlencoded
。
使用RestTemplate请求 content-type为 application/x-www-form-urlencoded
格式的步骤如下:
设置请求头
HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
在请求头中设置请求的content-type为application/x-www-form-urlencoded
设置请求参数
MultiValueMap<String, String> requestParam= new LinkedMultiValueMap<>(); requestParam.add("paramA", paramA); requestParam.add("paramB", paramB);
这里通过MultiValueMap设置请求参数,如果用get方式展示的话,格式类似于paramA=paramA¶mB=paramB
发送请求
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(requestParam, headers); ResponseEntity<String> responseEntity = restTemplate.exchange( requestUrl, HttpMethod.POST, requestEntity, String.class);
- 通过HttpEntity封装请求参数与headers
- 通过restTemplate.exchange方法发送请求,请求地址为requestUrl;请求方法为POST,请求参数为requestEntity,请求体数据格式为String
exchange的完整方法签名如下:
/** * Execute the HTTP method to the given URI template, writing the given request entity to the request, and * returns the response as {@link ResponseEntity}. * <p>URI Template variables are expanded using the given URI variables, if any. * @param url the URL * @param method the HTTP method (GET, POST, etc) * @param requestEntity the entity (headers and/or body) to write to the request * may be {@code null}) * @param responseType the type of the return value * @param uriVariables the variables to expand in the template * @return the response as entity * @since 3.0.2 */ <T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException;
我们直接引用注释的解释:
- 对给定的URI模板执行HTTP方法,将给定的请求实体写入请求,然后将响应返回为{@link ResponseEntity}。
-
URI模板变量使用给定的URI变量(如果有的话)进行扩展
- url —请求地址网址
- method —HTTP方法(GET、POST等)
- requestEntity —要写入请求的实体(头和/或正文),可能是{@code null})
- responseType —返回值的类型
- uriVariables —要在模板中展开的变量
- 最终以实体形式返回响应
解析返回参
// 这是一段防御代码
if (responseEntity == null) {
return null;
}
String checkResponseBody = responseEntity.getBody();
// 这是一段防御代码
if (StringUtils.isBlank(checkResponseBody)) {
return null;
}
通过 responseEntity.getBody()
获取响应体。
反序列化响应体为业务参数
通过上一步的代码,我们已经能够从响应中获取到responseBody。
接着就可以使用自己喜欢的方式将其反序列化为对象。我习惯使用jackson。
一段简单的反序列化代码如下:
JsonNode responseNode = OBJECT_MAPPER.readTree(checkResponseBody); String status = responseNode.get("paramA").asText(); String msg = responseNode.get("paramB").asText();
这里解析出来的结果用json方式展示就是如下的样式:
{ "paramA" : "paramA_value", "paramB" : "paramB_value", }
POST请求之发送json
除了上述的常见方式(表单提交)外,当前有些较为前卫的单位热衷于在请求阶段也发送json格式的数据,
相当于直接提交一个json文档。服务端需要对该json文档进行解析,从而完成一定的工作。
json格式的content-type为 application/json
这里直接引用之前笔者写的开源秒杀案例中的代码进行讲解。
设置请求头
// 构造要序列化为json的业务对象
QueryOrdersResponse queryOrdersResponse = new QueryOrdersResponse();
queryOrdersRequest.setSign(sign);
ObjectMapper objectMapper = new ObjectMapper();
// 组装请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);
// 构造请求体
HttpEntity<QueryOrdersRequest> httpEntity = new HttpEntity<>(queryOrdersRequest, headers);
- 构造待发送的业务实体,为其设置属性
- 组装请求头,设置content-type为 application/json
- 初始化HttpEntity, 通过有参构造方法设置业务实体与headers】
发送请求
// 2.发送请求 ResponseEntity<String> responseEntity = null; // 2.1 发起请求 responseEntity = restTemplate.postForEntity(queryOrdersUrl, httpEntity, String.class); System.out.println("----" + JSON.toJSONString(responseEntity));
json格式的请求可以直接通过restTemplate.postForEntity发送,它的完整方法签名如下
<T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException;
解析返回参数
接收到ResponseEntity之后,通过 responseEntity.getBody();获取到responseBody,解析方式就和上文中提到的一致了。
我们可以使用jackson/gson(笔者就不推荐用fastJson了,因为众人皆知的原因,八阿哥有点多啊……)来进行解析了。
// 2.2. 解析返回参数 String responseBody = responseEntity.getBody(); queryOrdersResponse = objectMapper.readValue(responseBody, QueryOrdersResponse.class); LOGGER.info("解析订单状态查询接口出参:[{}]", queryOrdersResponse.toString());
到此我们就实现了通过RestTemplate发送JSON格式的POST请求。
小结
本文偏应用实战,重点讲解了SpringBoot2.x版本中整合RestTemplate,并使用POST方法发送 application/x-www-form-urlencoded
及 application/json
两种超媒体文本的步骤。
方便自己以后能够快速落地,并希望能够对读者有所帮助。
相关原理解析会在未来的文章中发布,敬请期待。
版权声明:
原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。
原文
http://wuwenliang.net/2020/06/28/再谈RestTemplate实战应用/
本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 再谈RestTemplate实战应用