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
