笔者在两年前写过一篇RestTemplate使用相关的文章,地址: springboot中使用RestTemplate调用web服务小结 。
文章写作时SpringBoot版本尚在1.x徘徊,随着SpringBoot版本升级,有些用法在2.x版本中已经不适用。恰逢最近又用到了RestTemplate进行HTTP接口对接,
因此写作本文对最新的使用方法进行小结,方便后续参考,也希望能够帮到读者更好的使用RestTemplate在2.x的SpringBoot中进行HTTP接口的调用。
对于Get方式请求,2.x与1.x是兼容的,因此可以直接阅读上文中提到的链接,本文就不再重复赘述。
首先需要配置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请求方式最常见的就是表单提交,更加专业的说法就是: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);
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;
我们直接引用注释的解释:
// 这是一段防御代码 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", }
除了上述的常见方式(表单提交)外,当前有些较为前卫的单位热衷于在请求阶段也发送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);
// 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 两种超媒体文本的步骤。
方便自己以后能够快速落地,并希望能够对读者有所帮助。
相关原理解析会在未来的文章中发布,敬请期待。
版权声明:
原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。