Java分布式开发的时候我们需经常使用HttpClient 去进行远程调用 下面是封装的一个工具类 以后我们用的时候就可以直接用了
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.util.http.Utf8ResponseHandler;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import javax.annotation.PostConstruct;
import javax.net.ssl.SSLException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Slf4j
@Component("httpClient")
public class HttpClientUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class);
public static final String CONFIG_KEY_HTTP = "httpClient";
private RequestConfig config;
private static CloseableHttpClient client = null;
private static final int RETRY_TIME = 3;
@Autowired
private Environment env;
/**
* 注解 @PostConstruct 表示启动的时候执行该方法
*/
@PostConstruct
private void init() {
int poolSize = Integer.parseInt
(env.getProperty(CONFIG_KEY_HTTP+".poolSize"));
//读取目标服务器数据超时时间:SocketTimeout-->指的是连接上一个url,获取response的返回等待时
int socketTimeout = Integer.parseInt
(env.getProperty(CONFIG_KEY_HTTP+".socketTimeout"));
//连接目标服务器超时时间:ConnectionTimeout-->指的是连接一个url的连接等待时间
int connectTimeout = Integer.parseInt
(env.getProperty(CONFIG_KEY_HTTP+".connectTimeout"));
//从连接池获取连接的超时时间:ConnectionRequestTimeout
int connectionRequestTimeout = Integer.parseInt
(env.getProperty(CONFIG_KEY_HTTP+".connectionRequestTimeout"));
int defaultMaxPerRoute = Integer.parseInt
(env.getProperty(CONFIG_KEY_HTTP+".defaultMaxPerRoute"));
LOGGER.info(
"HttpClientUtil init. poolsize:{}, socketTimeout:{}, connectTimeout:{}, connectionRequestTimeout:{}, defaultMaxPerRoute:{}",
poolSize, socketTimeout, connectTimeout,
connectionRequestTimeout, defaultMaxPerRoute);
config = RequestConfig
.custom()
.setSocketTimeout(socketTimeout)
.setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectionRequestTimeout)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(poolSize);
cm.setDefaultMaxPerRoute(defaultMaxPerRoute);
//这个超时可以设置为客户端级别,作为所有请求的默认值:
client = HttpClients.custom().setDefaultRequestConfig(config).setConnectionManager(cm).build();
}
/**
* GET提交方式
*
* @param url
* @param params
* @return
*/
public String doGet(String url, Map<String, Object> params) throws UnsupportedEncodingException {
String apiUrl = url;
StringBuffer param = new StringBuffer();
CloseableHttpResponse response = null;
int i = 0;
for (String key : params.keySet()) {
if (i == 0) {
param.append("?");
} else {
param.append("&");
}
param.append(key).append("=").append(URLEncoder.encode(String.valueOf(params.get(key)), "utf-8"));
i++;
}
apiUrl += param;
String result = null;
HttpGet httpPost = new HttpGet(apiUrl);
try {
response = client.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (200 != statusCode) {
log.error(EntityUtils.toString(response.getEntity(), Consts.UTF_8));
}
HttpEntity entity = response.getEntity();
if (entity != null) {
result = EntityUtils.toString(entity);
}
} catch (IOException e) {
} finally {
httpPost.abort();
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* post提交表单,http参数是表单Form参数
*
* @param url
* @param map
* @param retry 是否重试,true时候,发送失败后重试,
* @return
* @throws ClientProtocolException
* @throws IOException
*/
public String postForm(String url, Map<String, Object> map, boolean retry)
throws ClientProtocolException, IOException {
Assert.notNull(url, "Error posting data, url is null.");
return postInner(retry, parseHttpPost(url, getPostParams(map)));
}
/**
* @param url
* @param method
* @param param
* @param retry 是否重试,true时候,发送失败后重试,
* @return
* @throws Exception
*/
public String postForm(String url, String method, String param, boolean retry) throws Exception {
Assert.notNull(url, "Error posting data, url is null.");
UrlEncodedFormEntity entity = HttpClientUtil.getEntity(method, param);
return postInner(retry, parseHttpPost(url, entity));
}
public static UrlEncodedFormEntity getEntity(String method, String param) throws UnsupportedEncodingException {
List<BasicNameValuePair> formparams = new ArrayList<BasicNameValuePair>();
formparams.add(new BasicNameValuePair("method", method));
formparams.add(new BasicNameValuePair("param", URLEncoder.encode(param, "UTF-8")));
UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
return uefEntity;
}
/**
* post提交表单,http参数是 Json参数
*
* @param url
* @param json
* @param retry
* @return
* @throws ClientProtocolException
* @throws IOException
*/
public String postJson(String url, String json, boolean retry)
throws ClientProtocolException, IOException {
Assert.notNull(url, "Error posting data, url is null.");
HttpPost parsedHttpPost = parseHttpPost(url, getPostParams(json));
parsedHttpPost.addHeader("Content-Type", "application/json");
return postInner(retry, parsedHttpPost);
}
/**
* 提交带有header参数的请求
* @param url
* @param json
* @param headers
* @param retry
* @return
* @throws IOException
*/
public String postWithHeader(String url, String json, Map<String, String> headers, Boolean retry) throws IOException {
Assert.notNull(url, "Error posting data, url is null.");
HttpPost parsedHttpPost = parseHttpPost(url, getPostParams(json));
if (headers != null) {
BasicHeader[] mHeaders = new BasicHeader[headers.size()];
BasicHeader header;
int index = 0;
for (Map.Entry<String, String> entry : headers.entrySet()) {
header = new BasicHeader(entry.getKey(), entry.getValue());
mHeaders[index] = header;
index += 1;
}
parsedHttpPost.setHeaders(mHeaders);
}
parsedHttpPost.addHeader("Content-Type", "application/json");
return postInner(retry, parsedHttpPost);
}
public String postSoap(String url, String soapXml, String soapAction) {
Assert.notNull(url, "Error posting data, url is null.");
HttpPost httpPost = new HttpPost(url);
String retStr = "";
try {
httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");
httpPost.setHeader("SOAPAction", soapAction);
StringEntity data = new StringEntity(soapXml,
Charset.forName("UTF-8"));
httpPost.setEntity(data);
CloseableHttpResponse response = client
.execute(httpPost);
HttpEntity httpEntity = response.getEntity();
if (httpEntity != null) {
// 打印响应内容
retStr = EntityUtils.toString(httpEntity, "UTF-8");
System.out.println("response:" + retStr);
}
} catch (Exception e) {
e.printStackTrace();
}
return retStr;
}
private String postInner(boolean retry, HttpPost httpPost)
throws ClientProtocolException, IOException {
CloseableHttpResponse response = null;
try {
response = client.execute(httpPost);
if (response.getStatusLine().getStatusCode() != 200) {
log.error(EntityUtils.toString(response.getEntity(), Consts.UTF_8));
return null;
}
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, Consts.UTF_8);
EntityUtils.consume(entity);
return result;
} catch (Exception e) {
throw e;
} finally {
httpPost.abort();
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private HttpPost parseHttpPost(String url, HttpEntity postParams) {
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(postParams);
return httpPost;
}
private HttpEntity getPostParams(Map<String, Object> params) {
if (params == null || params.size() == 0) {
return null;
}
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
Set<String> keySet = params.keySet();
for (String key : keySet) {
if (!ObjectUtils.isEmpty(params.get(key))) {
nvps.add(new BasicNameValuePair(key, params.get(key).toString()));
}
}
return new UrlEncodedFormEntity(nvps, Consts.UTF_8);
}
public HttpEntity getPostParams(String params) {
return new StringEntity(params, Consts.UTF_8);
}
class RetryHandler implements HttpRequestRetryHandler {
@Override
public boolean retryRequest(IOException exception, int executionCount,
HttpContext context) {
System.out.println(executionCount);
if (executionCount >= RETRY_TIME) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof InterruptedIOException) {
// Timeout
return false;
}
if (exception instanceof UnknownHostException) {
// Unknown host
return false;
}
if (exception instanceof ConnectTimeoutException) {
// Connection refused
return false;
}
if (exception instanceof SSLException) {
// SSL handshake exception
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
// 增加日志,便于确认是否重试
String sid = "";
if (null != request.getParams().getParameter("sid")) {
sid = request.getParams().getParameter("sid").toString();
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("sid = " + sid + " ,retryCount = "
+ executionCount);
}
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// Retry if the request is considered idempotent
return true;
}
return false;
}
};
/**
* post请求(用于key-value格式的参数)
* @param url
* @param params
* @return
*/
public static String doPost(String url, Map params){
BufferedReader in = null;
try {
// 定义HttpClient
HttpClient client = new DefaultHttpClient();
// 实例化HTTP方法
HttpPost request = new HttpPost();
request.setURI(new URI(url));
//设置参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
for (Iterator iter = params.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String value = String.valueOf(params.get(name));
nvps.add(new BasicNameValuePair(name, value));
//System.out.println(name +"-"+value);
}
request.setEntity(new UrlEncodedFormEntity(nvps,HTTP.UTF_8));
HttpResponse response = client.execute(request);
int code = response.getStatusLine().getStatusCode();
if(code == 200){ //请求成功
in = new BufferedReader(new InputStreamReader(response.getEntity()
.getContent(),"utf-8"));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
return sb.toString();
}
else{ //
System.out.println("状态码:" + code);
return null;
}
}
catch(Exception e){
e.printStackTrace();
return null;
}
}
/**
* post请求(用于请求json格式的参数)
* @param url
* @param params
* @return
*/
public static String doPost(String url, String params) throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);// 创建httpPost
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-Type", "application/json");
String charSet = "UTF-8";
StringEntity entity = new StringEntity(params, charSet);
httpPost.setEntity(entity);
CloseableHttpResponse response = null;
try {
response = httpclient.execute(httpPost);
StatusLine status = response.getStatusLine();
int state = status.getStatusCode();
if (state == HttpStatus.SC_OK) {
HttpEntity responseEntity = response.getEntity();
String jsonString = EntityUtils.toString(responseEntity);
return jsonString;
}
else{
logger.error("请求返回:"+state+"("+url+")");
}
}
finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}