httpclient初步封装
Http通信方式:
HttpURLConnection和HttpClient
HttpURLConnection是java的标准类,什么都没封装,用起来太原始,不方便
HttpClient就是一个增强版的HttpURLConnection,是apache的项目
HttpClient 两个版本:org.apache.commons.httpclient.HttpClient和org.apache.http.client.HttpClient
commons-httpclient 是 apache-commons 项目下的一个子项目,后来被 HttpComponents 取代,后者提供了更好的性能和更大的灵活性,所以尽量使用后者。
在HttpComponents4.1.1及以后版本的jar包中,DefaultHttpClient已过时,最新的4.5版本使用的CloseableHttpClient
但是公司用的org.apache.http.client.HttpClient 4.1版本,所以暂时学习下该版本的用法(公司网络限制,代码复制下来回去再测试,未完待续)
几个不错的博文参考
http://blog.csdn.net/wangpeng047/article/details/19624529
http://blog.csdn.net/a351945755/article/details/22782229
http://blog.csdn.net/rongyongfeikai2/article/details/41659353/
http://blog.csdn.net/xiaoxian8023/article/details/49865335
http://blog.csdn.net/faye0412/article/details/6883879
https://yq.aliyun.com/articles/294
http://xiaoa7.iteye.com/blog/1262034
http://blog.sina.com.cn/s/blog_5da93c8f0100t7wo.html
http://blog.sina.com.cn/s/blog_616e189f01018rpk.html
这是针对以xml报文方式请求接口地址封装的工具类,只是初步封装
package com.focustech.ins.modules.utils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.*; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.*; import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.util.HashMap; public class HttpUtil { private static Log logger = LogFactory.getLog(HttpUtil.class); // 总连接数 private static Integer maxTotal = Integer.valueOf(HttpCfgUtil.getProperty("maxTotal")); // 每个服务器的默认连接数,必须指定,否者默认是2 private static Integer defaultMaxPerRoute = Integer .valueOf(HttpCfgUtil.getProperty("defaultMaxPerRoute")); // 指定服务器的地址,每个指定服务器地址用逗号隔开 private static String routeHost = HttpCfgUtil.getProperty("routeHost"); // 指定服务器的连接数,每个指定服务器连接数用逗号隔开 private static String maxForRoute = HttpCfgUtil.getProperty("maxForRoute"); // 默认编码 private static String defaultEncode = HttpCfgUtil.getProperty("defaultEncode"); // 设定连接等待时间 private static Integer so_timeout = Integer.valueOf(HttpCfgUtil.getProperty("so_timeout")); // 设定连接超时时间 private static Integer connection_timeout = Integer .valueOf(HttpCfgUtil.getProperty("connection_timeout")); // 这几个对象都是通用设置,不存在线程安全问题,所以可以共用 private static HttpParams httpParams = createHttpParams(); private static SSLContext sslContext = createIgnoreVerifySSL(); private static SchemeRegistry schemeRegistry = new SchemeRegistry(); static { // 设置访问协议 schemeRegistry.register(new Scheme("http", 80, new PlainSocketFactory())); schemeRegistry.register(new Scheme("https", 443, new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER))); } // 连接管理器,ThreadSafeClientConnManager线程安全并且默认支持连接池 private ThreadSafeClientConnManager tscm = null; // 一个HttpClient维护一个池 private HttpClient client = null; private static HashMap<String, HttpUtil> cs = new HashMap<String, HttpUtil>(); // 根据公司编码创建池 private HttpUtil() { tscm = new ThreadSafeClientConnManager(schemeRegistry); client = new DefaultHttpClient(tscm, httpParams); initClientConnManager(tscm); } // 调用此类的接口才会创建池 // 按照接口地址去掉接口类型所得编码创建连接池 823001_01_04----》82300104 public static HttpUtil getInstance(String fixCode) { StringBuilder comAndNum = new StringBuilder(8); String codes[] = fixCode.split("_"); comAndNum.append(codes[0]).append(codes[2]); HttpUtil e = cs.get(comAndNum); if (e == null) { e = new HttpUtil(); cs.put(comAndNum.toString(), e); } return e; } // GET请求方式,默认请求头,utf-8编码 public String getMethod(String URI) throws IOException, URISyntaxException { HttpGet get = getHttpGet(URI); String result = getResponseEntity(get); return result; } // GET请求方式,默认请求头,自定义编码 public String getMethod(String URI, String encode) throws IOException, URISyntaxException { HttpGet get = getHttpGet(URI); String result = getResponseEntity(get); return result; } // GET请求方式,自定义请求头,utf-8编码 public String getMethod(HttpGet get) throws IOException { String result = getResponseEntity(get); return result; } // GET请求方式,自定义请求头,指定编码 public String getMethod(HttpGet get, String encode) throws IOException { initHeaders(get, encode); String result = getResponseEntity(get); return result; } // POST请求方式,默认请求头,utf-8编码 public String postMethod(String URI, String msg) throws URISyntaxException, IOException { HttpPost post = getHttpPost(URI); HttpEntity requestEntity = setRequestEntity(msg); post.setEntity(requestEntity); String result = getResponseEntity(post); return result; } // POST请求方式,默认请求头,指定编码 public String postMethod(String URI, String msg, String encode) throws URISyntaxException, IOException { HttpPost post = getHttpPost(URI, encode); HttpEntity requestEntity = setRequestEntity(msg, encode); post.setEntity(requestEntity); String result = getResponseEntity(post); return result; } // POST请求方式 流-》字节,默认请求头,utf-8编码 public byte[] postMethodToByte(String URI) throws URISyntaxException, IOException { HttpPost post = getHttpPost(URI); byte[] content = getResponseEntityToByte(post); return content; } // POST请求方式 流-》字节,默认请求头,指定编码 public byte[] postMethodToByte(String URI, String encode) throws URISyntaxException, IOException { HttpPost post = getHttpPost(URI, encode); byte[] content = getResponseEntityToByte(post); return content; } // POST请求方式,自定义请求头,utf-8编码 public String postMethod(HttpPost post, String msg) throws IOException { HttpEntity requestEntity = setRequestEntity(msg); post.setEntity(requestEntity); String result = getResponseEntity(post); return result; } // POST请求方式,自定义请求头,指定编码 public String postMethod(HttpPost post, String msg, String encode) throws IOException { initHeaders(post, encode); HttpEntity requestEntity = setRequestEntity(msg, encode); post.setEntity(requestEntity); String result = getResponseEntity(post); return result; } // 获取HttpGet对象,utf-8编码 public HttpGet getHttpGet(String URI) throws URISyntaxException { HttpGet get = new HttpGet(new URI(URI)); initHeaders(get); return get; } // 获取HttpGet对象,指定编码 public HttpGet getHttpGet(String URI, String encode) throws URISyntaxException { HttpGet get = new HttpGet(new URI(URI)); initHeaders(get, encode); return get; } // 获取HttpPost对象,utf-8编码 public HttpPost getHttpPost(String URI) throws URISyntaxException { HttpPost post = new HttpPost(new URI(URI)); initHeaders(post); return post; } // 获取HttpPost对象,指定编码 public HttpPost getHttpPost(String URI, String encode) throws URISyntaxException { HttpPost post = new HttpPost(new URI(URI)); initHeaders(post, encode); return post; } // 获取GET/POST响应内容 public String getResponseEntity(HttpRequestBase requestMethod) throws IOException { HttpEntity responseEntity = null; String result = null; HttpResponse response = null; try { response = client.execute(requestMethod); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { responseEntity = response.getEntity(); } if (responseEntity != null) result = EntityUtils.toString(responseEntity); } catch (IOException e) { e.printStackTrace(); }finally { EntityUtils.consume(responseEntity); } return result; } // 获取GET/POST响应内容流-》字节 public byte[] getResponseEntityToByte(HttpRequestBase requestMethod) throws IOException { HttpEntity responseEntity = null; byte[] content = null; HttpResponse response = null; try { response = client.execute(requestMethod); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { responseEntity = response.getEntity(); } if (responseEntity != null) content = EntityUtils.toByteArray(responseEntity); } catch (IOException e) { e.printStackTrace(); }finally { EntityUtils.consume(responseEntity); } return content; } // 设置POST请求体,msg表示报文,使用默认编码utf-8 public HttpEntity setRequestEntity(String msg) throws UnsupportedEncodingException { HttpEntity entity = null; if (msg != null) entity = new StringEntity(msg, defaultEncode); return entity; } // 设置POST请求体,msg表示报文,使用指定编码 public HttpEntity setRequestEntity(String msg, String encode) throws UnsupportedEncodingException { HttpEntity entity = null; if (msg != null) entity = new StringEntity(msg, encode); return entity; } // 设置默认的请求头,utf-8编码(可通过获取requestMethod自定义请求头) public void initHeaders(HttpRequestBase requestMethod) { requestMethod.setHeader("Content-Type", "text/xml;charset=" + defaultEncode); requestMethod.setHeader("Cache-Control", "no-cache"); requestMethod.setHeader("Pragma", "no-cache"); requestMethod.setHeader("Content-Type", "Expires"); requestMethod.setHeader("Accept-Charset", defaultEncode); } // 设置默认的请求头,指定编码 public void initHeaders(HttpRequestBase requestMethod, String encode) { requestMethod.setHeader("Content-Type", "text/xml;charset=" + encode); requestMethod.setHeader("Cache-Control", "no-cache"); requestMethod.setHeader("Pragma", "no-cache"); requestMethod.setHeader("Content-Type", "Expires"); requestMethod.setHeader("Accept-Charset", encode); } // 初始化ClientConnManager,设定并发数,不设定给出默认值 public void initClientConnManager(ThreadSafeClientConnManager tscm) { if (maxTotal != null) tscm.setMaxTotal(maxTotal); if (defaultMaxPerRoute != null) tscm.setDefaultMaxPerRoute(defaultMaxPerRoute); // 处理指定服务器的连接数设置 if (routeHost != null && !routeHost.equals("")) { String routeHosts[] = routeHost.split(","); String maxForRoutes[] = maxForRoute.split(","); for (int i = 0; i < routeHosts.length; i++) { String routeHost = routeHosts[i]; Integer maxForRoute = Integer.valueOf(maxForRoutes[i]); if (maxForRoute == null) break; HttpHost host = new HttpHost(routeHosts[i], maxForRoute); tscm.setMaxForRoute(new HttpRoute(host), maxForRoute); } } } // 创建HttpParams对象并指定超时时间 public static HttpParams createHttpParams() { HttpParams httpParams = new BasicHttpParams(); // 设定连接等待时间 if (so_timeout != null) httpParams.setParameter(HttpConnectionParams.SO_TIMEOUT, so_timeout); // 设定连接超时时间 if (connection_timeout != null) httpParams.setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, connection_timeout); return httpParams; } // 创建SSLContext对象用于绕过SSL验证 public static SSLContext createIgnoreVerifySSL() { SSLContext sc = null; try { sc = SSLContext.getInstance("TLS"); // 实现一个X509TrustManager接口,重写验证方法用于绕过SSL验证 X509TrustManager trustManager = new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } }; sc.init(null, new TrustManager[] { trustManager }, null); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } return sc; } // 关闭ThreadSafeClientConnManager,此方法会关闭一个池中所有连接,不要调用 public void release() { if (tscm != null) { tscm.shutdown(); } } }