1:单线程请求
请求方法如下
public String postXml(String url, String apiKeyAddr, String apiKey,String xml) throws Exception{
String responseString = "";
CloseableHttpClient httpclient = null;
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(apiKeyAddr);
String key = apiKey;
try {
keyStore.load(instream, key.toCharArray());
} finally {
instream.close();
}
try {
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,new String[] { "TLSv1" },null,SSLConnectionSocketFactory.getDefaultHostnameVerifier());
httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
} catch (Exception e) {
e.printStackTrace();
}
if(httpclient==null){
httpclient = HttpClients.createDefault();
}
try {
HttpPost httpPost = new HttpPost(url);
StringEntity params = new StringEntity(xml, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(params);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(30000).build();//设置请求和传输超时时间
httpPost.setConfig(requestConfig);
System.out.println("executing request:" + httpPost.getRequestLine());
System.out.println("executing request:" + EntityUtils.toString(httpPost.getEntity()));
CloseableHttpResponse response = httpclient.execute(httpPost);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
HttpEntity entity = response.getEntity();
try {
if(entity!=null){
responseString = EntityUtils.toString(entity,"UTF-8");
System.out.println(responseString);
EntityUtils.consume(entity);
}
} finally{
response.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(httpclient!=null){
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return responseString;
}
在实际处理过程中,单个请求是OK的,
2:多线程请求
private static CloseableHttpClient httpClient = null;
static {
httpClient = getInstance().getHttpClient();
}
private PoolingHttpClientConnectionManager getHttpClientConnectionManager(){
try {
// SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null,
// new TrustSelfSignedStrategy())
// .build();
// HostnameVerifier hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
// SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
// sslcontext,hostnameVerifier);
// KeyStore keyStore = KeyStore.getInstance("PKCS12");
// FileInputStream instream = new FileInputStream(apiKeyAddr);
// String key = apiKey;
// try {
// keyStore.load(instream, key.toCharArray());
// } finally {
// instream.close();
// }
// try {
// SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build();
// SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,new String[] { "TLSv1" },null,SSLConnectionSocketFactory.getDefaultHostnameVerifier());
// } catch (Exception e) {
// e.printStackTrace();
// }
ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", plainsf)
.register("https", sslsf)
.build();
PoolingHttpClientConnectionManager poolConnManager =
new PoolingHttpClientConnectionManager(socketFactoryRegistry);
// Increase max total connection to 200
poolConnManager.setMaxTotal(200);
// Increase default max connection per route to 20
poolConnManager.setDefaultMaxPerRoute(20);
SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(1000).build();
poolConnManager.setDefaultSocketConfig(socketConfig);
return poolConnManager;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private CloseableHttpClient getHttpClient() {
PoolingHttpClientConnectionManager poolConnManager = getHttpClientConnectionManager();
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(1000)
.setConnectTimeout(1000).setSocketTimeout(1000).build();
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(poolConnManager).setDefaultRequestConfig(requestConfig).build();
/**
* PoolStats
*
* leased :the number of persistent connections tracked by the connection manager currently being used to execute requests.
* available :the number idle persistent connections.
* pending : the number of connection requests being blocked awaiting a free connection.
* max: the maximum number of allowed persistent connections.
*/
if(poolConnManager!=null&&poolConnManager.getTotalStats()!=null) {
System.out.println("now client pool "+poolConnManager.getTotalStats().toString());
}
return httpClient;
}
private HttpClientUtil(){
}
public static HttpClientUtil getInstance(){
return new HttpClientUtil();
}
public static String postXml(String url, String param) {
String returnStr = null;
CloseableHttpResponse response = null;
HttpPost httpPost = new HttpPost(url);
try {
long currentTime=System.currentTimeMillis();
StringEntity params = new StringEntity(param, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(params);
System.out.println(currentTime+" 开始发送 请求:url"+url);
response = httpClient.execute(httpPost);
int status = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
if (status >= 200 && status < 300) {
String resopnse = "";
if(entity != null) {
resopnse = EntityUtils.toString(entity,"utf-8");
}
System.out.println(currentTime+" 接收响应:url"+url+" status="+status);
EntityUtils.consume(entity);
return entity != null ? resopnse : null;
} else {
System.out.println(currentTime+" 接收响应:url"+url+" status="+status+" resopnse="+EntityUtils.toString(entity,"utf-8"));
EntityUtils.consume(entity);
throw new ClientProtocolException("Unexpected response status: " + status);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(response != null){
response.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
httpPost.reset();
}
return returnStr;
}
这里用到了httpclient的连接池,实测500并发无忧
要点,
1.httpclient公用,所有请求交由连接池管理
2.请求配置超时时间,以便在请求处理完成之后连接池自动回收请求资源(此处为回收或重用,有待实测)