场景描述
restTemplate 是 spring 提供的基于 restful 设计的 http 请求客户端。
使用介绍
配置
springboot 默认提供了 restTemplate 相关的 Bean,但也可以通过手动注册同类型的 bean 来自定义一些配置,如通用的请求头,拦截器等。
1 2 3 4 5 6
| @Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory) { RestTemplate restTemplate = new RestTemplate(factory); return restTemplate; }
|
拦截器
一般的会将特定功能的拦截器,注册到独立的 restTemplate bean 中,即设置多个 restTemplate bean(默认同类型下只能存在一个 bean,可以使用包装类,装饰器)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class CustomInterceptor implements ClientHttpRequestInterceptor { @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { ... return execution.execute(request, body); } }
restTemplate.getInterceptors().add(new CustomInterceptor())
|
自定义消息转换器
项目中经常使用 FastJson
替换 Jackson
,实际上项目中存在一个 Json 处理工具即可,(Jackson
挺好用的,感觉 Bug 少多了)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public void setRestTemplate(RestTemplate restTemplate) { List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters(); List<HttpMessageConverter<?>> convertersValid = new ArrayList<>(); for (HttpMessageConverter<?> converter : converters) { if (converter instanceof MappingJackson2HttpMessageConverter || converter instanceof MappingJackson2XmlHttpMessageConverter) { continue; } convertersValid.add(converter); } convertersValid.add(fastJsonHttpMessageConverter()); restTemplate.setMessageConverters(convertersValid); }
private FastJsonHttpMessageConverter fastJsonHttpMessageConverter() { List<MediaType> mediaTypes = new ArrayList<>(); mediaTypes.add(MediaType.APPLICATION_JSON); FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat); fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter(); gsonHttpMessageConverter.setSupportedMediaTypes(mediaTypes); FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); fastConverter.setSupportedMediaTypes(mediaTypes); fastConverter.setFastJsonConfig(fastJsonConfig); return fastConverter; }
|
Get 参数设置
使用 restful 占位符,设置方式和 controller 层一致,如:
1 2 3 4 5 6 7
| void testGetParam() { restTemplate.getForObject( 'route?param1={param1}¶m2={param2}', T.class, ...参数 ) }
|
ps:当然参数也可以使用 Map
List 类型结果
对于任意使用 List 的结果集,在泛型类型设置上,使用 T[].class
替代,可以很好的避免 List<?> 无法获取具体类型的问题。
当然也可以使用 new ParameterizedTypeReference<List<T>>(){}
,但其本身是通过生成匿名类(类中的泛型不会被擦除)的方式来记录泛型信息。
使用数组类型无疑更简洁优雅。
使用 exchange 方法
1 2 3 4 5 6 7 8 9 10 11
| void testExchange() { HttpHeaders requestHeaders = new HttpHeaders(); HttpEntity<UserModel[]> request = new HttpEntity<>(requestHeaders); val result = restTemplate.exchange( "路由", HttpMethod.GET, request, T[].class, ...参数 ).getBody(); }
|
使用 execute 方法
1 2 3 4 5 6 7 8 9 10 11 12 13
| void testExecute() { HttpHeaders requestHeaders = new HttpHeaders(); HttpEntity<UserModel[]> request = new HttpEntity<>(requestHeaders); val requestCallback = restTemplate.httpEntityCallback(request, T[].class); val responseExtractor = restTemplate.responseEntityExtractor(T[].class); val result = restTemplate.execute( "路由", HttpMethod.GET, requestCallback, responseExtractor, ...参数 ); }
|