HttpUtil.java package com.sunon.util;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.nio.charset.Charset;import java.nio.charset.
package com.sunon.util; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.KeyStore; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.net.ssl.SSLContext; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.lang3.CharEncoding; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.entity.GzipDecompressingEntity; 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.methods.HttpRequestBase; import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 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.BasicNameValuePair; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.SSLContexts; import org.apache.http.ssl.TrustStrategy; import org.apache.http.util.EntityUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** *功 能:HTTP请求工具类
*版 权:Copyright (c) 2016
*创建时间:2016年12月9日 下午12:14:48
* * @author 王建 * @version 1.0 */ public class HttpUtil { private static final Logger LOG = LogManager.getLogger(HttpUtil.class); /** * HttpClient 连接池 */ private static PoolingHttpClientConnectionManager cm = null; static { // 初始化连接池,可用于请求HTTP/HTTPS(信任所有证书) cm = new PoolingHttpClientConnectionManager(getRegistry()); // 整个连接池最大连接数 cm.setMaxTotal(200); // 每路由最大连接数,默认值是2 cm.setDefaultMaxPerRoute(5); } /** * 发送 HTTP GET请求 *不带请求参数和请求头
* * @param url 地址 * @return * @throws Exception */ public static String httpGet(String url) throws Exception { HttpGet httpGet = new HttpGet(url); return doHttp(httpGet); } /** * 发送 HTTP GET请求 *带请求参数,不带请求头
* * @param url 地址 * @param params 参数 * @return * @throws Exception * @throws Exception */ public static String httpGet(String url, Mapparams) throws Exception { // 转换请求参数 List pairs = covertParams2NVPS(params); // 装载请求地址和参数 URIBuilder ub = new URIBuilder(); ub.setPath(url); ub.setParameters(pairs); HttpGet httpGet = new HttpGet(ub.build()); return doHttp(httpGet); } /** * 发送 HTTP GET请求 * 带请求参数和请求头
* * @param url 地址 * @param headers 请求头 * @param params 参数 * @return * @throws Exception * @throws Exception */ public static String httpGet(String url, Mapheaders, Map params) throws Exception { // 转换请求参数 List pairs = covertParams2NVPS(params); // 装载请求地址和参数 URIBuilder ub = new URIBuilder(); ub.setPath(url); ub.setParameters(pairs); HttpGet httpGet = new HttpGet(ub.build()); // 设置请求头 for (Map.Entry param : headers.entrySet()) httpGet.addHeader(param.getKey(), String.valueOf(param.getValue())); return doHttp(httpGet); } /** * 发送 HTTP POST请求 * 不带请求参数和请求头
* * @param url 地址 * @return * @throws Exception */ public static String httpPost(String url) throws Exception { HttpPost httpPost = new HttpPost(url); return doHttp(httpPost); } /** * 发送 HTTP POST请求 *带请求参数,不带请求头
* * @param url 地址 * @param params 参数 * @return * @throws Exception */ public static String httpPost(String url, Mapparams) throws Exception { // 转换请求参数 List pairs = covertParams2NVPS(params); HttpPost httpPost = new HttpPost(url); // 设置请求参数 httpPost.setEntity(new UrlEncodedFormEntity(pairs, StandardCharsets.UTF_8.name())); return doHttp(httpPost); } /** * 发送 HTTP POST请求 * 带请求参数和请求头
* * @param url 地址 * @param headers 请求头 * @param params 参数 * @return * @throws Exception */ public static String httpPost(String url, Mapheaders, Map params) throws Exception { // 转换请求参数 List pairs = covertParams2NVPS(params); HttpPost httpPost = new HttpPost(url); // 设置请求参数 httpPost.setEntity(new UrlEncodedFormEntity(pairs, StandardCharsets.UTF_8.name())); // 设置请求头 for (Map.Entry param : headers.entrySet()) httpPost.addHeader(param.getKey(), String.valueOf(param.getValue())); return doHttp(httpPost); } /** * 发送 HTTP POST请求,参数格式JSON * 请求参数是JSON格式,数据编码是UTF-8
* * @param url * @param param * @return * @throws Exception */ public static String httpPostJson(String url, String param) throws Exception { HttpPost httpPost = new HttpPost(url); // 设置请求头 httpPost.addHeader("Content-Type", "application/json; charset=UTF-8"); // 设置请求参数 httpPost.setEntity(new StringEntity(param, StandardCharsets.UTF_8.name())); return doHttp(httpPost); } /** * 发送 HTTP POST请求,参数格式XML *请求参数是XML格式,数据编码是UTF-8
* * @param url * @param param * @return * @throws Exception */ public static String httpPostXml(String url, String param) throws Exception { HttpPost httpPost = new HttpPost(url); // 设置请求头 httpPost.addHeader("Content-Type", "application/xml; charset=UTF-8"); // 设置请求参数 httpPost.setEntity(new StringEntity(param, StandardCharsets.UTF_8.name())); return doHttp(httpPost); } /** * 发送 HTTPS POST请求 *使用指定的证书文件及密码,不带请求头信息
* * @param url * @param param * @param path * @param password * @return * @throws Exception * @throws Exception */ public static String httpsPost(String url, String param, String path, String password) throws Exception { HttpPost httpPost = new HttpPost(url); // 设置请求参数 httpPost.setEntity(new StringEntity(param, StandardCharsets.UTF_8.name())); return doHttps(httpPost, path, password); } /** * 发送 HTTPS POST请求 *使用指定的证书文件及密码,请求头为“application/xml;charset=UTF-8”
* * @param url * @param param * @param path * @param password * @return * @throws Exception * @throws Exception */ public static String httpsPostXml(String url, String param, String path, String password) throws Exception { HttpPost httpPost = new HttpPost(url); // 设置请求头 httpPost.addHeader("Content-Type", "application/xml; charset=UTF-8"); // 设置请求参数 httpPost.setEntity(new StringEntity(param, StandardCharsets.UTF_8.name())); return doHttps(httpPost, path, password); } /** * 使用HTTP GET请求下载文件 * @param url 请求地址 * @param path 文件路径 * @throws Exception */ public static void httpGetDownload(String url, String path) throws Exception { CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build(); HttpGet httpGet = new HttpGet(url); doDownload(httpClient, httpGet, path); } /** * 使用HTTP POST请求下载文件 * @param url 请求地址 * @param path 文件路径 * @throws Exception */ public static void httpPostDownload(String url, String path) throws Exception { CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build(); HttpPost httpPost = new HttpPost(url); doDownload(httpClient, httpPost, path); } /** * 将Map键值对拼接成QueryString字符串,UTF-8编码 * @param params * @return * @throws Exception */ public static String getQueryStr(Mapparams) throws Exception { return URLEncodedUtils.format(covertParams2NVPS(params), CharEncoding.UTF_8); } /** * 将JavaBean属性拼接成QueryString字符串,UTF-8编码 * @param bean * @return * @throws Exception */ public static String getQueryStr(Object bean) throws Exception { // 将JavaBean转换为Map Map map = SignUtil.beanToSortedMap(bean); return URLEncodedUtils.format(covertParams2NVPS(map), CharEncoding.UTF_8); } /** * 将表单字符串转换为JavaBean * @param queryStr 表单字符串 * @param clazz {@link Class}待转换的JavaBean * @return * @throws Exception */ public static T parseNVPS2Bean(String queryStr, Class clazz) throws Exception { // 将“表单字符串”形式的字符串解析成NameValuePair集合 List list = URLEncodedUtils.parse(queryStr, Charset.forName(CharEncoding.UTF_8)); Map rsMap = new HashMap (); // 将NameValuePair集合中的参数装载到Map中 for (NameValuePair nvp : list) rsMap.put(nvp.getName(), nvp.getValue()); // 实例化JavaBean对象 T t = clazz.newInstance(); // 将Map键值对装载到JavaBean中 BeanUtils.populate(t, rsMap); return t; } /** * 转换请求参数,将Map键值对拼接成QueryString字符串 * * @param params * @return */ public static String covertParams2QueryStr(Map params) { List pairs = covertParams2NVPS(params); return URLEncodedUtils.format(pairs, StandardCharsets.UTF_8.name()); } /** * 转换请求参数 * * @param params * @return */ public static List covertParams2NVPS(Map params) { List pairs = new ArrayList (); for (Map.Entry param : params.entrySet()) pairs.add(new BasicNameValuePair(param.getKey(), String.valueOf(param.getValue()))); return pairs; } /** * 发送 HTTP 请求 * * @param request * @return * @throws Exception */ private static String doHttp(HttpRequestBase request) throws Exception { // 通过连接池获取连接对象 CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build(); return doRequest(httpClient, request); } /** * 发送 HTTPS 请求 * 使用指定的证书文件及密码
* * @param request * @param path * @param password * @return * @throws Exception * @throws Exception */ private static String doHttps(HttpRequestBase request, String path, String password) throws Exception { // 获取HTTPS SSL证书 SSLConnectionSocketFactory csf = getSSLFactory(path, password); // 通过连接池获取连接对象 CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build(); return doRequest(httpClient, request); } /** * 获取HTTPS SSL连接工厂 *使用指定的证书文件及密码
* * @param path 证书全路径 * @param password 证书密码 * @return * @throws Exception * @throws Exception */ private static SSLConnectionSocketFactory getSSLFactory(String path, String password) throws Exception { // 初始化证书,指定证书类型为“PKCS12” KeyStore keyStore = KeyStore.getInstance("PKCS12"); // 读取指定路径的证书 FileInputStream input = new FileInputStream(new File(path)); try { // 装载读取到的证书,并指定证书密码 keyStore.load(input, password.toCharArray()); } finally { input.close(); } // 获取HTTPS SSL证书连接上下文 SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, password.toCharArray()).build(); // 获取HTTPS连接工厂,指定TSL版本 SSLConnectionSocketFactory sslCsf = new SSLConnectionSocketFactory(sslContext, new String[] { "SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2" }, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); return sslCsf; } /** * 获取HTTPS SSL连接工厂 *跳过证书校验,即信任所有证书
* * @return * @throws Exception */ private static SSLConnectionSocketFactory getSSLFactory() throws Exception { // 设置HTTPS SSL证书信息,跳过证书校验,即信任所有证书请求HTTPS SSLContextBuilder sslBuilder = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }); // 获取HTTPS SSL证书连接上下文 SSLContext sslContext = sslBuilder.build(); // 获取HTTPS连接工厂 SSLConnectionSocketFactory sslCsf = new SSLConnectionSocketFactory(sslContext, new String[] { "SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2" }, null, NoopHostnameVerifier.INSTANCE); return sslCsf; } /** * 获取 HTTPClient注册器 * * @return * @throws Exception */ private static RegistrygetRegistry() { Registry registry = null; try { registry = RegistryBuilder. create().register("http", new PlainConnectionSocketFactory()) .register("https", getSSLFactory()).build(); } catch (Exception e) { LOG.error("获取 HTTPClient注册器失败", e); } return registry; } /** * 处理Http/Https请求,并返回请求结果 * 注:默认请求编码方式 UTF-8
* * @param httpClient * @param request * @return * @throws Exception */ private static String doRequest(CloseableHttpClient httpClient, HttpRequestBase request) throws Exception { String result = null; CloseableHttpResponse response = null; try { // 获取请求结果 response = httpClient.execute(request); // 解析请求结果 HttpEntity entity = response.getEntity(); // 如果响应结果是GZIP格式的,则进行解压缩 String contentType = entity.getContentType().getValue(); if (StringUtils.equals(contentType, "application/x-gzip")) entity = new GzipDecompressingEntity(entity); // 将HTTP响应数据流转换为字符串 result = EntityUtils.toString(entity, StandardCharsets.UTF_8.name()); // 关闭IO流 EntityUtils.consume(entity); } finally { if (null != response) response.close(); } return result; } /** * 使用HTTP请求下载文件 * @param httpClient * @param request * @param filePath 文件路径 * @throws Exception */ private static void doDownload(CloseableHttpClient httpClient, HttpRequestBase request, String filePath) throws Exception { CloseableHttpResponse response = null; try { // 获取请求结果 response = httpClient.execute(request); // 解析请求结果 HttpEntity entity = response.getEntity(); // 转换结果 byte[] bs = EntityUtils.toByteArray(entity); // 将字节数组通过文件流写入路径path下的本地文件中 save(bs, filePath); // 关闭IO流 EntityUtils.consume(entity); } finally { if (response != null) response.close(); } } /** * 使用NIO将字节数组写入文件中 * @param bs 字节数组 * @param filePath 文件路径 * @throws Exception */ private static void save(byte[] bs, String filePath) throws Exception { FileOutputStream fout = null; try { // 初始化文件输出流 fout = new FileOutputStream(filePath); // 根据文件流获取文件通道 FileChannel fc = fout.getChannel(); // 将字节数组写入缓冲区 ByteBuffer buffer = ByteBuffer.wrap(bs); // 将缓冲区中的数据保存在文件中 fc.write(buffer); } finally { if (fout != null) { fout.flush(); fout.close(); } } } }