javascript
【Spring Boot】RestTemplate使用总结
【問題背景】
最近一直在處理交接項目的遺留問題,在確定了商品同步方案之后,與商品服務對接,遇到了一個問題,請求Read time out。
【原調用方式】
和我交接項目的人,采用的是和舊系統一樣的調用方式,寫了個HttpClient工具類,之前和我對接接口就給我發了請求超時的錯誤信息,現在看來這個問題一直都沒有處理。
【原方式處理方案】
其實這個問題很簡單,既然是請求讀取時間超時,那我們在發起請求的時候,將讀取時間設置長一些,就解決了。項目中,使用的HttpClient版本是4.3,所以,我在他的請求工具類中增加了一段設置讀取時間的代碼:
//post方式請求 public String doPost(String url, Map<String, Object> map){HttpPost httpPost = new HttpPost(url); //設置代理主機HttpHost proxy=new HttpHost("請求服務的ip地址", 36016);//設置請求的連接超時時間RequestConfig config=RequestConfig.custom().setProxy(proxy).setConnectTimeout(30000).setSocketTimeout(100000).build();// 裝載配置信息httpPost.setConfig(config);//裝填參數List<NameValuePair> nvps = new ArrayList<>();if(map!=null){for (Map.Entry<String, Object> entry : map.entrySet()) {Object value = entry.getValue();String valueStr = value==null?null:value.toString();nvps.add(new BasicNameValuePair(entry.getKey(),valueStr ));}}//設置header信息//指定報文頭【Content-type】、【User-Agent】httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");try{//設置參數到請求對象中httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));// 發起請求CloseableHttpResponse response = this.httpClient.execute(httpPost);int statusCode = response.getStatusLine().getStatusCode();log.info("返回http狀態碼:"+statusCode);// 判斷狀態碼是否為200if ( statusCode == 200) {// 返回響應體的內容HttpEntity httpEntity = response.getEntity();if(httpEntity!=null && httpEntity.getContent()!=null){return getResponseString(httpEntity);}}return null;}catch (Exception e){e.printStackTrace();return null;}}連接超時的問題就解決了。但另一個問題是,這個項目調用的不僅僅是一個項目,我設置了商品調用的請求主機,但其他接口是調用另一個項目,這就不對了。要不然我就在工具類代碼中在單獨寫一個post請求商品服務的方法,這樣代碼就重復了。想到既然用的是Spring Boot架構,我就將原生的HttpClient請求方式棄用了,直接使用Spring Boot中封裝的更好的RestTemplate去處理。
【新調用方式配置】
采用RestTemplate方式調用其實也很簡單,寫一個全局配置,并且設置超時時間即可,代碼如下:
@Configuration public class RestTemplateConfig {@Bean@ConditionalOnMissingBean({ RestOperations.class, RestTemplate.class })//Spring Boot的自動配置機制依靠@ConditionalOnMissingBean注解判斷是否執行初始化代碼,// 即如果用戶已經創建了bean,則相關的初始化代碼不再執行。public RestTemplate restTemplate(ClientHttpRequestFactory factory) {RestTemplate restTemplate = new RestTemplate(factory);// 使用 utf-8 編碼集的 conver 替換默認的 conver(默認的 string conver 的編碼集為"ISO-8859-1")List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();while (iterator.hasNext()) {HttpMessageConverter<?> converter = iterator.next();if (converter instanceof StringHttpMessageConverter) {iterator.remove();}}messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));//解決微信返回text/plain的解析restTemplate.getMessageConverters().add(new WxMappingJackson2HttpMessageConverter());return restTemplate;}@Bean@ConditionalOnMissingBean({ClientHttpRequestFactory.class})public ClientHttpRequestFactory simpleClientHttpRequestFactory() {SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();//設置超時時間factory.setReadTimeout(15000);// msfactory.setConnectTimeout(15000);// msreturn factory;} }【新調用方式使用】
項目中如何發起調用請求,核心代碼如下:
//設置請求頭HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); //調用參數MultiValueMap<String, String> params= new LinkedMultiValueMap<>();params.add("companyId",companyId.toString());params.add("addGoodsList",new Gson().toJson(wmsGoodsDtos));params.add("editGoodsList",new Gson().toJson(editWmsGoodsDtos));params.add("deleteGoodsIdList",deleteList);params.add("platformId",platformId.toString());HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers); // 執行HTTP請求 // 最后的參數需要用String.class 使用其他的會報錯ResponseEntity<String> response = restTemplate.exchange("請求的接口地址", HttpMethod.POST, requestEntity, String.class);String result = response.getBody();【總結】
現在大多是Spring Boot,Spring Cloud服務架構,既然有了新的架構,為什么還要把舊系統的一些老東西拿過來使用呢,換了一種方式,更好地解決了問題,也學習到了一些新東西,何樂而不為呢。
總結
以上是生活随笔為你收集整理的【Spring Boot】RestTemplate使用总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS3(animation, tras
- 下一篇: 3DMM配置