概述
RestTemplate是spring內置的http請求封裝,在使用spring的情況下,http請求直接使用RestTemplate是不錯的選擇。
Rest服務端
使用RestTemplate發起http請求的時候,Rest服務提供者沒有什么特殊要求,直接按照傳統的SpringMVC的Controller層實現方式實現即可。
舉例:
@RestController @RequestMapping("/user") public class UserController { private Logger logger = LoggerFactory.getLogger(UserController.class); @RequestMapping("/add") public UserBean add(UserBean userBean) { logger.info("request param:{}", JSON.toJSON(userBean)); return userBean; } }
Rest客戶端
使用RestTemplate前先得做一些初始化處理,比如指定http客戶端工廠類、設置超時時間、響應參數轉換器等。
初始化RestTemplate
@Configuration @ConditionalOnClass(value = {RestTemplate.class, HttpClient.class}) public class RestTemplateConfiguration { @Value("${remote.maxTotalConnect:0}") private int maxTotalConnect; //連接池的最大連接數默認為0 @Value("${remote.maxConnectPerRoute:200}") private int maxConnectPerRoute; //單個主機的最大連接數 @Value("${remote.connectTimeout:2000}") private int connectTimeout; //連接超時默認2s @Value("${remote.readTimeout:30000}") private int readTimeout; //讀取超時默認30s //創建HTTP客戶端工廠 private ClientHttpRequestFactory createFactory() { if (this.maxTotalConnect <= 0) { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(this.connectTimeout); factory.setReadTimeout(this.readTimeout); return factory; } HttpClient httpClient = HttpClientBuilder.create().setMaxConnTotal(this.maxTotalConnect) .setMaxConnPerRoute(this.maxConnectPerRoute).build(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory( httpClient); factory.setConnectTimeout(this.connectTimeout); factory.setReadTimeout(this.readTimeout); return factory; } //初始化RestTemplate,並加入spring的Bean工廠,由spring統一管理 @Bean @ConditionalOnMissingBean(RestTemplate.class) public RestTemplate getRestTemplate() { RestTemplate restTemplate = new RestTemplate(this.createFactory()); List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters(); //重新設置StringHttpMessageConverter字符集為UTF-8,解決中文亂碼問題 HttpMessageConverter<?> converterTarget = null; for (HttpMessageConverter<?> item : converterList) { if (StringHttpMessageConverter.class == item.getClass()) { converterTarget = item; break; } } if (null != converterTarget) { converterList.remove(converterTarget); } converterList.add(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); //加入FastJson轉換器 converterList.add(new FastJsonHttpMessageConverter4()); return restTemplate; } }
StringHttpMessageConverter默認使用的字符集是ISO-8859-1,在遇到中文的時候會有亂碼,所以需要移除RestTemplate默認的StringHttpMessageConverter修改字符字符集后重新設置。
spring的json轉換器默認使用的是Jackson,json字符串和對應的Entity如果有字段對不上就會報錯,這個有點不符合國情,而FastJson則不會報錯,所以很多時候都會用FastJSON替換默認的Jackson。
FastJSON替換Jackson配置
@Configuration public class FastjsonConfiguration { @Bean public HttpMessageConverters fastjsonConverter() { FastJsonConfig fastJsonConfig = new FastJsonConfig(); //自定義格式化輸出 fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullNumberAsZero); FastJsonHttpMessageConverter4 fastjson = new FastJsonHttpMessageConverter4(); fastjson.setFastJsonConfig(fastJsonConfig); return new HttpMessageConverters(fastjson); } }
RestTemplate使用舉例
以MultiValueMap
傳參
@Test
public void multiValueMapParam() { MultiValueMap<String, String> requestParam = new LinkedMultiValueMap<>(); requestParam.set("name", "張三"); UserBean result = restTemplate .postForObject("http://127.0.0.1:8280/user/add", requestParam, UserBean.class); logger.info("result:{}", JSON.toJSON(result)); }
以Entity
傳參
@Test public void restClient() { UserBean userBean = new UserBean(); userBean.setName("王五"); String result = restTemplate .postForObject("http://127.0.0.1:8280/user/add", userBean, String.class); logger.info("result:{}", result); }
以Entity傳參,接收端Controller以Entity接收參數的時候需加上@RequestBody
注解,否則接收不到參數。
@RequestMapping("/add") public UserBean add(@RequestBody UserBean userBean) { logger.info("request param:{}", JSON.toJSON(userBean)); return userBean; }
原文地址:http://www.itclj.com/blog/5925894681c06e672f942ad6
demo地址:https://github.com/clj198606061111/spring-boot-rest-template-demo