支持可配置的連接池, 單例的httpclinet, 更好的response handle
package zhwb.util;
import org.apache.http.HttpHost;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* The type Custom http component.
*
* @author jack.zhang
*/
@Component
public class CustomHttpComponent {
private static final Logger LOG = LoggerFactory.getLogger(CustomHttpComponent.class);
private static final int MAX_TOTAL = 200;
private static final int DEFAULT_TIMEOUT = 200;
private HttpClient httpClient;
/**
* Instantiates a new Custom http component.
* 單個站點最大允許連接:200
* 單個站點最大允許連接數:200
* 默認連接超時時間:200ms
* 默認數據接收超時時間:200ms
*/
public CustomHttpComponent() {
PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
connectionManager.setDefaultMaxPerRoute(MAX_TOTAL);
connectionManager.setMaxTotal(MAX_TOTAL);
HttpParams httpParams = new BasicHttpParams();
httpParams.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, DEFAULT_TIMEOUT);
httpParams.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, DEFAULT_TIMEOUT);
httpClient = new DefaultHttpClient(connectionManager);
}
/**
* Instantiates a new Custom http component.
*
* @param maxPerRoute 單個站點最大允許連接
* @param maxTotal 單個站點最大允許連接數
* @param connTimeout 連接超時時間
* @param soTimeout 數據接收超時時間
* @param staleConnCheck 是否進行陳舊連接檢查, 如果不開啓, 則啓動陳舊連接關閉線程
*/
public CustomHttpComponent(int maxPerRoute, int maxTotal, int connTimeout, int soTimeout, boolean staleConnCheck) {
PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
connectionManager.setDefaultMaxPerRoute(maxPerRoute);
connectionManager.setMaxTotal(maxTotal);
HttpParams httpParams = new BasicHttpParams();
httpParams.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connTimeout);
httpParams.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, soTimeout);
httpParams.setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, staleConnCheck);
if (!staleConnCheck) {
new IdleConnectionMonitorThread(connectionManager).start();
}
httpClient = new DefaultHttpClient(connectionManager);
}
/**
* Execute t.
*
* @param httpHost the http host
* @param httpUriRequest the http uri request
* @param handler the handler
* @return the t
* @throws java.io.IOException the iO exception
*/
public <T> T execute(HttpHost httpHost, HttpUriRequest httpUriRequest, AbstractResponseHandler<T> handler) throws IOException {
return httpClient.execute(httpHost, httpUriRequest, handler, new BasicHttpContext());
}
/**
* Execute t.
*
* @param httpUriRequest the http uri request
* @param handler the handler
* @return the t
* @throws java.io.IOException the iO exception
*/
public <T> T execute(HttpUriRequest httpUriRequest, AbstractResponseHandler<T> handler) throws IOException {
return httpClient.execute(httpUriRequest, handler, new BasicHttpContext());
}
public void shutdown() {
LOG.debug("Connection manager is shutting down");
httpClient.getConnectionManager().shutdown();
LOG.debug("Connection manager shut down");
}
/**
* The type Idle connection monitor thread.
*
* @author jack.zhang
*/
public class IdleConnectionMonitorThread extends Thread {
private final ClientConnectionManager connMgr;
private volatile boolean shutdown;
/**
* Instantiates a new Idle connection monitor thread.
*
* @param connMgr the conn mgr
*/
public IdleConnectionMonitorThread(ClientConnectionManager connMgr) {
super();
this.connMgr = connMgr;
}
@Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(5000);
// Close expired connections
connMgr.closeExpiredConnections();
// Optionally, close connections
// that have been idle longer than 30 sec
connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
}
}
} catch (InterruptedException ex) {
LOG.warn("exception occur, " + ex.getMessage());
}
}
/**
* Shutdown void.
*/
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}
}
package zhwb.util;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.IOException;
/**
* @author jack.zhang
*/
public abstract class AbstractResponseHandler<T> implements ResponseHandler<T> {
public static final int HTTP_UNSUCCESS_CODE = 300;
@Override
public T handleResponse(HttpResponse response) throws IOException {
StatusLine statusLine = response.getStatusLine();
HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= HTTP_UNSUCCESS_CODE) {
EntityUtils.consume(entity);
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
return handle(entity);
}
public abstract T handle(HttpEntity entity) throws IOException;
}
package zhwb.util;
import org.apache.http.HttpEntity;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
/**
* @author jack.zhang
*/
public class BasicResponseHandler extends AbstractResponseHandler<String> {
@Override
public String handle(HttpEntity entity) throws IOException {
return entity == null ? null : EntityUtils.toString(entity);
}
}