javascript
【Spring Boot】RestTemplate使用总结
【問題背景】
最近一直在處理交接項(xiàng)目的遺留問題,在確定了商品同步方案之后,與商品服務(wù)對(duì)接,遇到了一個(gè)問題,請求Read time out。
【原調(diào)用方式】
和我交接項(xiàng)目的人,采用的是和舊系統(tǒng)一樣的調(diào)用方式,寫了個(gè)HttpClient工具類,之前和我對(duì)接接口就給我發(fā)了請求超時(shí)的錯(cuò)誤信息,現(xiàn)在看來這個(gè)問題一直都沒有處理。
【原方式處理方案】
其實(shí)這個(gè)問題很簡單,既然是請求讀取時(shí)間超時(shí),那我們在發(fā)起請求的時(shí)候,將讀取時(shí)間設(shè)置長一些,就解決了。項(xiàng)目中,使用的HttpClient版本是4.3,所以,我在他的請求工具類中增加了一段設(shè)置讀取時(shí)間的代碼:
//post方式請求 public String doPost(String url, Map<String, Object> map){HttpPost httpPost = new HttpPost(url); //設(shè)置代理主機(jī)HttpHost proxy=new HttpHost("請求服務(wù)的ip地址", 36016);//設(shè)置請求的連接超時(shí)時(shí)間RequestConfig config=RequestConfig.custom().setProxy(proxy).setConnectTimeout(30000).setSocketTimeout(100000).build();// 裝載配置信息httpPost.setConfig(config);//裝填參數(shù)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 ));}}//設(shè)置header信息//指定報(bào)文頭【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{//設(shè)置參數(shù)到請求對(duì)象中httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));// 發(fā)起請求CloseableHttpResponse response = this.httpClient.execute(httpPost);int statusCode = response.getStatusLine().getStatusCode();log.info("返回http狀態(tài)碼:"+statusCode);// 判斷狀態(tài)碼是否為200if ( statusCode == 200) {// 返回響應(yīng)體的內(nèi)容HttpEntity httpEntity = response.getEntity();if(httpEntity!=null && httpEntity.getContent()!=null){return getResponseString(httpEntity);}}return null;}catch (Exception e){e.printStackTrace();return null;}}連接超時(shí)的問題就解決了。但另一個(gè)問題是,這個(gè)項(xiàng)目調(diào)用的不僅僅是一個(gè)項(xiàng)目,我設(shè)置了商品調(diào)用的請求主機(jī),但其他接口是調(diào)用另一個(gè)項(xiàng)目,這就不對(duì)了。要不然我就在工具類代碼中在單獨(dú)寫一個(gè)post請求商品服務(wù)的方法,這樣代碼就重復(fù)了。想到既然用的是Spring Boot架構(gòu),我就將原生的HttpClient請求方式棄用了,直接使用Spring Boot中封裝的更好的RestTemplate去處理。
【新調(diào)用方式配置】
采用RestTemplate方式調(diào)用其實(shí)也很簡單,寫一個(gè)全局配置,并且設(shè)置超時(shí)時(shí)間即可,代碼如下:
@Configuration public class RestTemplateConfig {@Bean@ConditionalOnMissingBean({ RestOperations.class, RestTemplate.class })//Spring Boot的自動(dòng)配置機(jī)制依靠@ConditionalOnMissingBean注解判斷是否執(zhí)行初始化代碼,// 即如果用戶已經(jīng)創(chuàng)建了bean,則相關(guān)的初始化代碼不再執(zhí)行。public RestTemplate restTemplate(ClientHttpRequestFactory factory) {RestTemplate restTemplate = new RestTemplate(factory);// 使用 utf-8 編碼集的 conver 替換默認(rèn)的 conver(默認(rèn)的 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();//設(shè)置超時(shí)時(shí)間factory.setReadTimeout(15000);// msfactory.setConnectTimeout(15000);// msreturn factory;} }【新調(diào)用方式使用】
項(xiàng)目中如何發(fā)起調(diào)用請求,核心代碼如下:
//設(shè)置請求頭HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); //調(diào)用參數(shù)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); // 執(zhí)行HTTP請求 // 最后的參數(shù)需要用String.class 使用其他的會(huì)報(bào)錯(cuò)ResponseEntity<String> response = restTemplate.exchange("請求的接口地址", HttpMethod.POST, requestEntity, String.class);String result = response.getBody();【總結(jié)】
現(xiàn)在大多是Spring Boot,Spring Cloud服務(wù)架構(gòu),既然有了新的架構(gòu),為什么還要把舊系統(tǒng)的一些老東西拿過來使用呢,換了一種方式,更好地解決了問題,也學(xué)習(xí)到了一些新東西,何樂而不為呢。
總結(jié)
以上是生活随笔為你收集整理的【Spring Boot】RestTemplate使用总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS3(animation, tras
- 下一篇: javascript “||”、“”的运