1.RestTemplate添加RequestHeader如content-type可通過httpclient設置
List<Header> headers = new ArrayList<>(); headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36")); headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate")); headers.add(new BasicHeader("Accept-Language", "zh-CN")); headers.add(new BasicHeader("Connection", "Keep-Alive")); httpClientBuilder.setDefaultHeaders(headers); HttpClient httpClient = httpClientBuilder.build(); // httpClient連接配置,底層是配置RequestConfig HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
restTemplate.setRequestFactory(clientHttpRequestFactory);
2.使用中進行異常處理
try catch
public String postRemoteData(ParameterRo ro) throws UnsupportedEncodingException { /** * 設置請求頭 */ HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8")); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); /** * POST請求參數,根據需要進行封裝 */ String bodyData = new String(Base64Util.encodeData(JSON.toJSONString(ro)).getBytes("UTF-8"), "UTF-8"); /** * 查看HttpEntity的構造方法,包含只有請求頭和只有請求體的情況 */ HttpEntity<String> httpEntity = new HttpEntity<String>(bodyData, headers); /** * 執行操作 */ String result = restTemplate.postForObject(remoteUrl, httpEntity, String.class); return result; }
3.控制超時,使用連接池,編碼轉換
RestTemplate是Spring提供的用於訪問Rest服務的客戶端,RestTemplate提供了多種便捷訪問遠程Http服務的方法,能夠大大提高客戶端的編寫效率。
調用RestTemplate的默認構造函數,RestTemplate對象在底層通過使用java.net包下的實現創建HTTP 請求,可以通過使用ClientHttpRequestFactory指定不同的HTTP請求方式。
ClientHttpRequestFactory接口主要提供了兩種實現方式
- 一種是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)創建底層的Http請求連接。
- 一種方式是使用HttpComponentsClientHttpRequestFactory方式,底層使用HttpClient訪問遠程的Http服務,使用HttpClient可以配置連接池和證書等信息。
RestTemplate默認是使用SimpleClientHttpRequestFactory,內部是調用jdk的HttpConnection,默認超時為-1
public RestTemplate(ClientHttpRequestFactory requestFactory) { this(); setRequestFactory(requestFactory); }
其中,第二個構造方法中可以傳入ClientHttpRequestFactory參數,第一個進行默認初始化,因為我們經常需要對請求超時進行設置並能 夠對超時進行后續處理,而第 一個構造方法,我們無法控制超時時間,第二個構造中的ClientHttpRequestFactory接口的實現類中存在 timeout屬性,因此選用第二個構造方法
//創建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; }
@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); }
@Component @Lazy(false) public class RestClient { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleRestClient.class); private static RestTemplate restTemplate; static { // 長連接保持30秒 PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS); // 總連接數 pollingConnectionManager.setMaxTotal(1000); // 同路由的並發數 pollingConnectionManager.setDefaultMaxPerRoute(1000); HttpClientBuilder httpClientBuilder = HttpClients.custom(); httpClientBuilder.setConnectionManager(pollingConnectionManager); // 重試次數,默認是3次,沒有開啟 httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(2, true)); // 保持長連接配置,需要在頭添加Keep-Alive httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()); // RequestConfig.Builder builder = RequestConfig.custom(); // builder.setConnectionRequestTimeout(200); // builder.setConnectTimeout(5000); // builder.setSocketTimeout(5000); // // RequestConfig requestConfig = builder.build(); // httpClientBuilder.setDefaultRequestConfig(requestConfig); List<Header> headers = new ArrayList<>(); headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36")); headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate")); headers.add(new BasicHeader("Accept-Language", "zh-CN")); headers.add(new BasicHeader("Connection", "Keep-Alive")); httpClientBuilder.setDefaultHeaders(headers); HttpClient httpClient = httpClientBuilder.build(); // httpClient連接配置,底層是配置RequestConfig HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); // 連接超時 clientHttpRequestFactory.setConnectTimeout(5000); // 數據讀取超時時間,即SocketTimeout clientHttpRequestFactory.setReadTimeout(5000); // 連接不夠用的等待時間,不宜過長,必須設置,比如連接不夠用時,時間過長將是災難性的 clientHttpRequestFactory.setConnectionRequestTimeout(200); // 緩沖請求數據,默認值是true。通過POST或者PUT大量發送數據時,建議將此屬性更改為false,以免耗盡內存。 // clientHttpRequestFactory.setBufferRequestBody(false); // 添加內容轉換器 List<HttpMessageConverter<?>> messageConverters = new ArrayList<>(); messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8"))); messageConverters.add(new FormHttpMessageConverter()); messageConverters.add(new MappingJackson2XmlHttpMessageConverter()); messageConverters.add(new MappingJackson2HttpMessageConverter()); restTemplate = new RestTemplate(messageConverters); restTemplate.setRequestFactory(clientHttpRequestFactory); restTemplate.setErrorHandler(new DefaultResponseErrorHandler()); LOGGER.info("RestClient初始化完成"); } private RestClient() { } @PostConstruct public static RestTemplate getClient() { return restTemplate; } }
參考網頁:http://blog.csdn.net/clj198606061111/article/details/70227571,http://blog.csdn.net/u010476464/article/details/50067079,http://www.cnblogs.com/winner-0715/p/6258139.html