httpclient的使用(一)
最近工作中经常调用第三方接口,选择使用了httpclient,简单记录下代码的实现过程
`
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
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.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
/**
http请求的工具类
/
public class HttpClientUtil {
private static final Logger log = LoggerFactory.getLogger(HttpClientUtil.class);
/*- 初始化HttpClient
*/
private CloseableHttpClient httpClient = HttpClients.createDefault();
/**
- POST方式调用
- @param url
- @param params 参数为NameValuePair键值对对象
- @return 响应字符串
- @throws java.io.UnsupportedEncodingException
*/
public String executeByPOST(String url, List params) {
HttpPost post = new HttpPost(url);
ResponseHandler responseHandler = new BasicResponseHandler();
String responseJson = null;
try {
if (params != null) {
post.setEntity(new UrlEncodedFormEntity(params));
}
responseJson = httpClient.execute(post, responseHandler);
log.info("HttpClient POST请求结果:" + responseJson);
}
catch (ClientProtocolException e) {
e.printStackTrace();
log.info("HttpClient POST请求异常:" + e.getMessage());
}
catch (IOException e) {
e.printStackTrace();
}
finally {
httpClient.getConnectionManager().closeExpiredConnections();
httpClient.getConnectionManager().closeIdleConnections(30, TimeUnit.SECONDS);
}
return responseJson;
}
/**
- Get方式请求
- @param url 带参数占位符的URL,例:http://ip/User/user/center.aspx?_action=GetSimpleUserInfo&codes={0}&email={1}
- @param params 参数值数组,需要与url中占位符顺序对应
- @return 响应字符串
- @throws java.io.UnsupportedEncodingException
*/
public String executeByGET(String url, Object[] params) {
String messages = MessageFormat.format(url, params);
HttpGet get = new HttpGet(messages);
ResponseHandler responseHandler = new BasicResponseHandler();
String responseJson = null;
try {
responseJson = httpClient.execute(get, responseHandler);
log.info("HttpClient GET请求结果:" + responseJson);
}
catch (ClientProtocolException e) {
e.printStackTrace();
log.error("HttpClient GET请求异常:" + e.getMessage());
}
catch (IOException e) {
e.printStackTrace();
log.error("HttpClient GET请求异常:" + e.getMessage());
}
finally {
httpClient.getConnectionManager().closeExpiredConnections();
httpClient.getConnectionManager().closeIdleConnections(30, TimeUnit.SECONDS);
}
return responseJson;
}
/**
- @param url
- @return
*/
public String executeByGET(String url) {
HttpGet get = new HttpGet(url);
ResponseHandler responseHandler = new BasicResponseHandler();
String responseJson = null;
try {
responseJson = httpClient.execute(get, responseHandler);
log.info("HttpClient GET请求结果:" + responseJson);
}
catch (ClientProtocolException e) {
e.printStackTrace();
log.error("HttpClient GET请求异常:" + e.getMessage());
}
catch (IOException e) {
e.printStackTrace();
log.error("HttpClient GET请求异常:" + e.getMessage());
}
finally {
httpClient.getConnectionManager().closeExpiredConnections();
httpClient.getConnectionManager().closeIdleConnections(30, TimeUnit.SECONDS);
}
return responseJson;
}
/**
- https posp请求,可以绕过证书校验
- @param url
- @param params
- @return
*/
public static final String sendHttpsRequestByPost(String url, Map<String, String> params) {
String responseContent = null;
HttpClient httpClient = new DefaultHttpClient();
//创建TrustManager
X509TrustManager xtm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
- 初始化HttpClient
//这个好像是HOST验证
X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
public void verify(String arg0, SSLSocket arg1) throws IOException {}
public void verify(String arg0, String[] arg1, String[] arg2) throws SSLException {}
public void verify(String arg0, X509Certificate arg1) throws SSLException {}
};
try {
//TLS1.0与SSL3.0基本上没有太大的差别,可粗略理解为TLS是SSL的继承者,但它们使用的是相同的SSLContext
SSLContext ctx = SSLContext.getInstance("TLS");
//使用TrustManager来初始化该上下文,TrustManager只是被SSL的Socket所使用
ctx.init(null, new TrustManager[] { xtm }, null);
//创建SSLSocketFactory
SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
socketFactory.setHostnameVerifier(hostnameVerifier);
//通过SchemeRegistry将SSLSocketFactory注册到我们的HttpClient上
httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", socketFactory, 443));
HttpPost httpPost = new HttpPost(url);
List formParams = new ArrayList(); // 构建POST请求的表单参数
for (Map.Entry<String, String> entry : params.entrySet()) {
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity(); // 获取响应实体
if (entity != null) {
responseContent = EntityUtils.toString(entity, "UTF-8");
}
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭连接,释放资源
httpClient.getConnectionManager().shutdown();
}
return responseContent;
}
/**
- 发送HTTP_POST请求,json格式数据
- @param url
- @param body
- @return
- @throws Exception
/
public static String sendPostByJson(String url, String body,String token) throws Exception {
CloseableHttpClient httpclient = HttpClients.custom().build();
HttpPost post = null;
String resData = null;
CloseableHttpResponse result = null;
try {
post = new HttpPost(url);
HttpEntity entity2 = new StringEntity(body, Consts.UTF_8);
post.setConfig(RequestConfig.custom().setConnectTimeout(30000).setSocketTimeout(30000).build());
post.setHeader("Content-Type", "application/json");
post.setHeader("Authorization","bearer "+token);
post.setEntity(entity2);
result = httpclient.execute(post);
if (HttpStatus.SC_OK == result.getStatusLine().getStatusCode()) {
resData = EntityUtils.toString(result.getEntity());
}
} finally {
if (result != null) {
result.close();
}
if (post != null) {
post.releaseConnection();
}
httpclient.close();
}
return resData;
}
public static String sendPostByJson(String url, String body) throws Exception {
CloseableHttpClient httpclient = HttpClients.custom().build();
HttpPost post = null;
String resData = null;
CloseableHttpResponse result = null;
try {
post = new HttpPost(url);
HttpEntity entity2 = new StringEntity(body, Consts.UTF_8);
post.setConfig(RequestConfig.custom().setConnectTimeout(30000).setSocketTimeout(30000).build());
post.setHeader("Content-Type", "application/json");
post.setEntity(entity2);
result = httpclient.execute(post);
if (HttpStatus.SC_OK == result.getStatusLine().getStatusCode()) {
resData = EntityUtils.toString(result.getEntity());
}
} finally {
if (result != null) {
result.close();
}
if (post != null) {
post.releaseConnection();
}
httpclient.close();
}
return resData;
}
/* - 发送HTTP_GET请求
- @see 该方法会自动关闭连接,释放资源
- @param requestURL 请求地址(含参数)
- @param decodeCharset 解码字符集,解析响应数据时用之,其为null时默认采用UTF-8解码
- @return 远程主机响应正文
*/
public static String sendGetRequest(String reqURL, String decodeCharset){
long responseLength = 0; //响应长度
String responseContent = null; //响应内容
HttpClient httpClient = new DefaultHttpClient(); //创建默认的httpClient实例
HttpGet httpGet = new HttpGet(reqURL); //创建org.apache.http.client.methods.HttpGet
try{
HttpResponse response = httpClient.execute(httpGet); //执行GET请求
HttpEntity entity = response.getEntity(); //获取响应实体
if(null != entity){
responseLength = entity.getContentLength();
responseContent = EntityUtils.toString(entity, decodeCharset==null ? "UTF-8" : decodeCharset);
EntityUtils.consume(entity); //Consume response content
}
System.out.println("请求地址: " + httpGet.getURI());
System.out.println("响应状态: " + response.getStatusLine());
System.out.println("响应长度: " + responseLength);
System.out.println("响应内容: " + responseContent);
}catch(ClientProtocolException e){
log.debug("该异常通常是协议错误导致,比如构造HttpGet对象时传入的协议不对(将‘http‘写成‘htp‘)或者服务器端返回的内容不符合HTTP协议要求等,堆栈信息如下", e);
}catch(ParseException e){
log.debug(e.getMessage(), e);
}catch(IOException e){
log.debug("该异常通常是网络原因引起的,如HTTP服务器未启动等,堆栈信息如下", e);
}finally{
httpClient.getConnectionManager().shutdown(); //关闭连接,释放资源
}
return responseContent;
}
}
`