同步httpclient
当客户端请求数量不是非常大,请求Response RT时间在能接受范围时,这种方式更适合。
public class SyncHttpClients {
private static Logger logger = Logger.getLogger(HttpClientUtil.class);
private final static String DEFAULT_CHARSETNAME = "UTF-8";
private final static int DEFAULT_TIMEOUT = 5000;
private static MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
static {
httpConnectionManager.getParams().setDefaultMaxConnectionsPerHost(3);
httpConnectionManager.getParams().setMaxTotalConnections(30);
httpConnectionManager.getParams().setConnectionTimeout(3000);
httpConnectionManager.getParams().setSoTimeout(5000);
httpConnectionManager.getParams().setTcpNoDelay(true);
httpConnectionManager.getParams().setStaleCheckingEnabled(false);
httpConnectionManager.getParams().setLinger(1);
httpConnectionManager.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler(1, false));
Protocol myhttps = new Protocol("https", new HTTPSSecureProtocolSocketFactory(), 443);
Protocol.registerProtocol("https", myhttps);
}
/**
* 根据url获取ResponseBody,method=get
* @param url exp:http://192.168.1.1/api.do
* @param charsetName 默认使用UTF-8编码
* @return 以String的方式返回
* @throws UnsupportedEncodingException
*/
public static String getDataAsStringFromUrl(String url, String charsetName) {
return getDataAsStringFromUrl(url, charsetName, DEFAULT_TIMEOUT);
}
public static String getDataAsStringFromUrl(String url) {
return getDataAsStringFromUrl(url, null, DEFAULT_TIMEOUT);
}
public static String getDataAsStringFromUrl(String url, int timeout) {
return getDataAsStringFromUrl(url, null, timeout);
}
/**
* 根据url获取ResponseBody,method=get
* @param url exp:http://192.168.1.1/api.do
* @return 以byte[]的方式放回
*/
private static byte[] getDataFromUrl(String url, int timeout) {
if (StringUtils.isBlank(url)) {
logger.error("url is blank!");
return null;
}
HttpClient httpClient = new HttpClient(httpConnectionManager);
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(3000);
httpClient.getParams().setSoTimeout(timeout);
GetMethod method = new GetMethod(url);
method.setFollowRedirects(false);
try {
int statusCode = httpClient.executeMethod(method);
if (statusCode == HttpStatus.SC_OK) {
return method.getResponseBody();
} else {
throw new RuntimeException("http request error,return code:" + statusCode + ",msg:"
+ new String(method.getResponseBody()));
}
} catch (HttpException e) {
logger.error("url:" + url, e);
} catch (IOException e) {
logger.error("url:" + url, e);
} finally {
method.releaseConnection();
}
return null;
}
/**
* 探测url是否正常,返回200 ok表示正常
* @param url
* @return
*/
public static boolean testUrlIsOk(String url) {
if (StringUtils.isBlank(url)) {
return false;
}
if (!SecurityUrlCheck.checkUrl(url)) {
logger.error("url is not security!");
return false;
}
HttpClient httpClient = new HttpClient();
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(1000);
httpClient.getParams().setSoTimeout(2000);
GetMethod method = new GetMethod(url);
method.setFollowRedirects(false);
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(1, false));
try {
int statusCode = httpClient.executeMethod(method);
if (statusCode == HttpStatus.SC_OK) {
return true;
}
} catch (HttpException e) {
} catch (IOException e) {
} finally {
method.releaseConnection();
}
return false;
}
public static String getDataAsStringFromUrl(String url, String charsetName, int timeout) {
if (StringUtils.isBlank(url)) {
logger.error("url is blank!");
return null;
}
if (StringUtils.isBlank(charsetName)) {
charsetName = DEFAULT_CHARSETNAME;
}
byte[] responseBody = getDataFromUrl(url, timeout);
if (null != responseBody) {
try {
return new String(responseBody, charsetName);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e.getMessage());
}
}
return null;
}
/**
* 根据url获取ResponseBody,method=post
*/
public static String getDataAsStringFromPostUrl(String url, Map map) {
return getDataAsStringFromPostUrl(url, map, DEFAULT_TIMEOUT);
}
public static String getDataAsStringFromPostUrl(String url, Map map, int timeout) {
return getDataAsStringFromPostUrl(url, map, timeout, null);
}
public static String getDataAsStringFromPostUrl(String url, String jsonBody, int timeout,
Map httpMethodParams) {
Assert.hasText(url, "url can not be blank!");
HttpClient httpClient = new HttpClient(httpConnectionManager);
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(3000);
httpClient.getHttpConnectionManager().getParams().setSoTimeout(timeout);
httpClient.getParams().setSoTimeout(timeout);
PostMethod method = new PostMethod(url);
method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, DEFAULT_CHARSETNAME);
if (null != httpMethodParams) {
for (Map.Entry entry : httpMethodParams.entrySet()) {
method.getParams().setParameter(entry.getKey(), entry.getValue());
}
}
RequestEntity se;
try {
se = new StringRequestEntity(jsonBody, "application/json", "UTF-8");
method.setRequestEntity(se);
int statusCode = httpClient.executeMethod(method);
if (statusCode == HttpStatus.SC_OK) {
return new String(method.getResponseBody(), DEFAULT_CHARSETNAME);
} else {
throw new RuntimeException("http request error,return code:" + statusCode + ",msg:"
+ new String(method.getResponseBody()));
}
} catch (HttpException e) {
logger.error("HttpException url request error:" + url, e);
} catch (IOException e) {
logger.error("IOException url request error:" + url, e);
} finally {
method.releaseConnection();
}
return null;
}
public static String getDataAsStringFromPostUrl(String url, Map map, int timeout,
Map httpMethodParams) {
Assert.hasText(url, "url can not be blank!");
HttpClient httpClient = new HttpClient(httpConnectionManager);
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(3000);
httpClient.getHttpConnectionManager().getParams().setSoTimeout(timeout);
httpClient.getParams().setSoTimeout(timeout);
PostMethod method = new PostMethod(url);
method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, DEFAULT_CHARSETNAME);
if (null != httpMethodParams) {
for (Map.Entry entry : httpMethodParams.entrySet()) {
method.getParams().setParameter(entry.getKey(), entry.getValue());
}
}
if (null != map) {
for (Map.Entry entry : map.entrySet()) {
method.setParameter(entry.getKey(), entry.getValue());
}
}
try {
int statusCode = httpClient.executeMethod(method);
if (statusCode == HttpStatus.SC_OK) {
return new String(method.getResponseBody(), DEFAULT_CHARSETNAME);
} else {
throw new RuntimeException("http request error,return code:" + statusCode + ",msg:"
+ new String(method.getResponseBody()));
}
} catch (HttpException e) {
logger.error(e.getMessage());
} catch (IOException e) {
logger.error(e.getMessage());
} finally {
method.releaseConnection();
}
return new RuntimeException("Exception appear in httpClient");
}
}
异步httpClient
反之相对同步httpclient,如果请求response的RT时间超出业务接受范围,则只能改用异步,需要一个callBack类来处理异步response
public class AsyncHttpClients {
public static Logger logger = LoggerFactory.getLogger(AsyncHttpClients.class);
private static final int HTTP_CODE_SUCCESS = 200;
private static AsyncHttpClient asyncHttpClient;
static {
DefaultAsyncHttpClientConfig.Builder configBuilder = new DefaultAsyncHttpClientConfig.Builder();
configBuilder.setMaxConnections(20000);
configBuilder.setMaxConnectionsPerHost(200);
configBuilder.setReadTimeout(3000);
configBuilder.setRequestTimeout(3000);
configBuilder.setConnectTimeout(1000);
configBuilder.setMaxRequestRetry(0);
configBuilder.setTcpNoDelay(true);
configBuilder.setDisableUrlEncodingForBoundRequests(true);
configBuilder.setThreadPoolName("AsyncHttpClients");
DefaultAsyncHttpClientConfig cf = configBuilder.build();
asyncHttpClient = new DefaultAsyncHttpClient(cf);
}
public static void postUrlFormBody(String url, AsyncHttpClientCallBack callback) {
postUrlFormBody(url, null, callback);
}
/**
* 异步任务
* @param url
* @param paramMap
* @param callback
*/
public static void postUrlFormBody(final String url, Map paramMap,
final AsyncHttpClientCallBack callback) {
List params = new ArrayList<>();
if (!CollectionUtils.isEmpty(paramMap)) {
Iterator itr = paramMap.keySet().iterator();
while (itr.hasNext()) {
String name = itr.next();
params.add(new Param(name, paramMap.get(name)));
}
}
asyncHttpClient.preparePost(url).addQueryParams(params).execute(new AsyncCompletionHandler() {
@Override
public Response onCompleted(Response response) throws Exception {
if (response.getStatusCode() == HTTP_CODE_SUCCESS) {
callback.requestCompleted(true, response.getResponseBody(), null);
} else {
callback.requestCompleted(false, null,
"request error,http code:" + response.getStatusCode() + ",url:" + url);
}
return null;
}
@Override
public void onThrowable(Throwable t) {
callback.requestCompleted(false, null, "request error,url:" + url + ",case by " + t.getMessage());
}
});
}
}
----------------------分割线----------------------------
/** 处理异步response的callBack函数 **/
public interface AsyncHttpClientCallBack {
void requestCompleted(boolean success, String data, String errorMsg);
}
使用
public class HttpclientTest {
@Test
public void syncHttpclientTest() {
String url = "http://127.0.0.1/api.do";
/** HTTP GET **/
String syncGet = SyncHttpClients.getDataAsStringFromUrl(url);
AsyncHttpClients.postUrlFormBody(url, new AsyncHttpClientCallBack() {
@Override
public void requestCompleted(boolean success, String data, String errorMsg) {
if (success) {
} else {
}
}
});
/** HTTP POST **/
HashMap paramMap = new HashMap() {
{
put("key", "value");
}
};
String responsePost = SyncHttpClients.getDataAsStringFromPostUrl(url, paramMap);
AsyncHttpClients.postUrlFormBody(url, paramMap, new AsyncHttpClientCallBack() {
@Override
public void requestCompleted(boolean success, String data, String errorMsg) {
if (success) {
} else {
}
}
});
}
}