tags: [RestTemplate]
categories: [springboot]
前言
在SpringBoot中,去除了很多繁杂的配置,而使用公用的配置和模块来集成类似的功能,在SpringBoot3.0引入的RestTemplate即是典型的对于同步的请求做了统一的封装(异步请求AsyncRestTemplate已经废弃,建议使用SpringBoot5.0的WebClient),前几天看了同事的代码,发现对于RestTemplate的使用理解还差点,正好研究下
execute介绍
先说一下这个方法,观察平时使用的各种请求方式最终都会落到这个重载的doExecute方法上来
默认情况下,整个流程是
- 创建RestTemplate对象,载入默认的各种消息处理器,ClientHttpRequestFactory和UriTemplate
- 根据传入的参数,使用ClientHttpRequestFactory根据URL和Method来创建请求,并设置Header
- 执行请求操作,异常情况使用默认的异常处理器处理,默认使用的是JDK自带的HttpClient请求,正常情况下会根据Header中的ContentType属性或者接收对象类型来确定使用具体的消息转换器来处理信息,最后包装响应体,返回响应结果
基本使用
虽然实际使用方法多,但都是根据请求方法和响应体类型区分而已,所以具体使用起来并不复杂
根据请求类型分,有GET、POST、PUT、DELETE、PATCH、OPTION、HEAD七种请求方式
根据参数也能分为直接String字符串,Object对象形式和LinkedMap形式的表单提交方式
根据返回体类型,可以分为xxxForObject,xxxForEntity,exchange方法,第一个是直接返回响应体中的Body属性,第二个返回的是HttpEntity,包含有状态码和响应头,Exchange方法就可以自定定义请求方式了
自定义RestTemplate设置
如前所述,整个流程的消息转换器、异常处理器、Http请求框架和请求属性设置都可以自定义
自定义消息转换器
默认Spring使用的处理Json数据的是MappingJackson2HttpMessageConverter
,我也是偏向于使用jackson相关序列化工具,如果想要使用其他序列化工具在AbstractHttpMessageConverter
抽象类下有多种消息转换器,对于Jackson我们可以设置ObjectMapper来自定义序列化配置,这里就没配上了,生产中则最好配上统一的配置
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
//设置自定义的异常处理器
restTemplate.setErrorHandler(new RestTemplateExceptionHandler());
//设置自定义拦截器
restTemplate.setInterceptors(Collections.singletonList(interceptor));
//设置自定义消息转换器
restTemplate.setMessageConverters(Collections.singletonList(mappingJacksonHttpMessageConverter()));
//替换HttpS实现
return restTemplate;
}
@Bean
public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(restTemplateObjectMapper());
return converter;
}
@Bean
public ObjectMapper restTemplateObjectMapper() {
return new ObjectMapper();
}
自定义拦截器
一般都用来记录日志
@Component
@Slf4j
public class RestTemplateInterceptor implements ClientHttpRequestInterceptor {
@Override
@NonNull
public ClientHttpResponse intercept(HttpRequest request, @Nonnull byte[] body, ClientHttpRequestExecution execution) throws IOException {
Assert.notNull(request.getURI(), "请求路径不能为空");
Assert.notNull(request.getMethod(), "请求方法不能为空");
String rawPath = request.getURI().getRawPath();
String name = request.getMethod().name();
log.info("【RestTemplate请求】请求路径:{}, 请求方法:{}", rawPath, name);
return execution.execute(request, body);
}
}
自定义异常处理器
一般会指定相关的错误码和错误信息
@Slf4j
public class RestTemplateExceptionHandler extends DefaultResponseErrorHandler {
@Override
public void handleError(URI url, HttpMethod method, @Nullable ClientHttpResponse response) {
log.error("RestTemplate请求异常, url:{}, 请求方式:{}, 响应信息:{}", url.getPath(), method.name(), JsonUtil.toJson(response));
throw new BusinessException(ExceptionEnum.REST_TEMPLATE_EXCEPTION);
}
}
替换Http请求组件&设置连接属性
在SpringBoot中请求创建都是通过ClientHttpRequestFactory
来创建的,所以设置连接属性也是在这里设置,默认使用的HttpClient连接具体实现是SimpleClientHttpRequestFactory
,若想使用其他Http组件来创建连接则需要新建新的ClientHttpRequestFactory
来获取,比如okHttp对应的即为OkHttp3ClientHttpRequestFactory
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(1000);
factory.setConnectTimeout(6000);
return factory;
}