参考: 关于JAVA发送Https请求(HttpsURLConnection和HttpURLConnection) https://www.cnblogs.com/mengen/p/9138214.html
1、支持https:忽略证书验证过程
2、支持设置http请求参数、编码等
3、
package com.util.http;
import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.Map.Entry;
/**
* http、https 请求工具类
*/
public class HttpUtil {
private static final String CHARSET_UTF8 = "UTF-8";
private static final String METHOD_GET = "GET"; // GET
private static final String METHOD_POST = "POST";// POST
private static final int DEF_CONN_TIMEOUT = 5 * 1000;
private static final int DEF_READ_TIMEOUT = 60 * 1000;
public static final String CONTENT_TYPE_XFORM = "application/x-www-form-urlencoded";
public static final String CONTENT_TYPE_JSON = "application/json";
//最大接收报文长度4M
private static final int PACKAGE_MAXLEN = 4 * 1024 * 1024;
/**
* 初始化http请求参数,建立连接
*
* @param url
* @param method
* @param headers 请求头
* @return
* @throws Exception
*/
private static HttpURLConnection buildHttpConn(String url, String method, String contentType, Map<String, String> headers) throws Exception {
URL _url = new URL(url);
HttpURLConnection httpConn;
if (!isHttps(url)) {
httpConn = (HttpURLConnection) _url.openConnection();
} else {
httpConn = (HttpsURLConnection) _url.openConnection();
//JDK1.7默认支持TLSV1版本协议,JDK1.8默认支持TLSV1.2 解决协议版本兼容问题(TlsCompatSocketFactory)
//System.setProperty("https.protocols", "TLSv1");
SSLContext sslContext = SSLContext.getInstance("TLS");
//忽略证书验证过程
TrustManager[] tm = {new MyX509TrustManager()};
sslContext.init(null, tm, new java.security.SecureRandom());
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
((HttpsURLConnection) httpConn).setSSLSocketFactory(new TlsCompatSocketFactory(sslContext.getSocketFactory()));
// 设置域名校验
((HttpsURLConnection) httpConn).setHostnameVerifier(new TrustAnyHostnameVerifier());
}
// 连接超时
httpConn.setConnectTimeout(DEF_CONN_TIMEOUT);
// 读取超时
httpConn.setReadTimeout(DEF_READ_TIMEOUT);
//禁用缓存
httpConn.setUseCaches(false);
httpConn.setRequestMethod(method);
if (isEmptyString(contentType)) {
//默认表单内容
contentType = "application/x-www-form-urlencoded";
}
httpConn.setRequestProperty("Content-Type", contentType);
//httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//http.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
if (null != headers && !headers.isEmpty()) {
for (Entry<String, String> entry : headers.entrySet()) {
httpConn.setRequestProperty(entry.getKey(), entry.getValue());
}
}
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.connect();
return httpConn;
}
/**
* @param url
* @param method
* @param contentType
* @param headers
* @param reqData
* @param sendEncoding 发送数据编码
* @param rcvEncoding 接收数据编码
* @return
* @throws Exception
*/
public static String sendRequest(String url, String method, String contentType, Map<String, String> headers, String reqData, String sendEncoding, String rcvEncoding) throws Exception {
HttpURLConnection httpConn = null;
String responseStr = "";
if (isEmptyString(sendEncoding)) {
sendEncoding = CHARSET_UTF8;
}
if (isEmptyString(rcvEncoding)) {
rcvEncoding = CHARSET_UTF8;
}
try {
try {
httpConn = buildHttpConn(url, method, contentType, headers);
} catch (SSLHandshakeException e) {
}
if (METHOD_POST.equals(method) && !isEmptyString(reqData)) {
try (OutputStream out = httpConn.getOutputStream()) {
out.write(reqData.getBytes(sendEncoding));
out.flush();
}
}
//返回结果码处理
int rescode = httpConn.getResponseCode();
String resmsg = httpConn.getResponseMessage();
System.out.println("Server response: " + rescode + " " + resmsg);
if (rescode != 200) {
throw new Exception("Server response: " + rescode + " " + resmsg);
}
//读取服务器返回数据
try (BufferedInputStream bis = new BufferedInputStream(httpConn.getInputStream())) {
StringBuffer sb = new StringBuffer();
byte[] bfBytes = new byte[10240];
int len;
int sumlen = 0;
while ((len = bis.read(bfBytes)) != -1) {
//sb.append(new String(bfBytes, 0, len, rcvEncoding));
sb.append(new String(bfBytes, 0, len));
sumlen += len;
if (sumlen > PACKAGE_MAXLEN) {
throw new Exception("通讯接收报文超长");
}
}
//String默认编码ISO8859-1(单字节编码),编码转换为rcvEncoding
responseStr = new String(sb.toString().getBytes(), rcvEncoding);
}
} catch (Exception e) {
//TODO
e.printStackTrace();
throw e;
} finally {
if (httpConn != null) {
httpConn.disconnect();// 关闭连接
}
}
return responseStr;
}
public static String get(String url) throws Exception {
return get(url, null);
}
public static String get(String url, Map<String, String> params) throws Exception {
return get(url, null, params, null);
}
public static String get(String url, Map<String, String> headers, Map<String, String> params, String rcvEncoding) throws Exception {
return sendRequest(initParams(url, params), METHOD_GET, null, headers, null, null, rcvEncoding);
}
public static String post(String url, String contentType, String reqData) throws Exception {
return post(url, contentType, null, reqData, null, null);
}
public static String post(String url, String contentType, Map<String, String> headers, String reqData, String sendEncoding, String rcvEncoding) throws Exception {
return sendRequest(url, METHOD_POST, contentType, headers, reqData, sendEncoding, rcvEncoding);
}
/**
* 功能描述: 构造请求参数
*
* @return 返回类型:
* @throws Exception
*/
public static String initParams(String url, Map<String, String> params) throws Exception {
if (null == params || params.isEmpty()) {
return url;
}
StringBuilder sb = new StringBuilder(url);
if (url.indexOf("?") == -1) {
sb.append("?");
}
sb.append(map2Url(params));
return sb.toString();
}
/**
* map构造url
*
* @return 返回类型:
* @throws Exception
*/
public static String map2Url(Map<String, String> paramToMap) throws Exception {
if (null == paramToMap || paramToMap.isEmpty()) {
return null;
}
StringBuffer url = new StringBuffer();
boolean isfist = true;
for (Entry<String, String> entry : paramToMap.entrySet()) {
if (isfist) {
isfist = false;
} else {
url.append("&");
}
url.append(entry.getKey()).append("=");
String value = entry.getValue();
if (!isEmptyString(value)) {
url.append(URLEncoder.encode(value, CHARSET_UTF8));
}
}
return url.toString();
}
private static boolean isEmptyString(String s) {
return s == null || s.length() == 0;
}
/**
* 检测是否https
*
* @param url
*/
private static boolean isHttps(String url) {
return url.startsWith("https");
}
/**
* 信任任何证书
*/
private static class MyX509TrustManager implements X509TrustManager {
//检查客户端证书
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
//检查服务器端证书
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
//返回受信任的X509证书数组
return new X509Certificate[0];
}
}
/**
* https 域名校验
*
* @return
*/
private static class TrustAnyHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
}
package com.util.http;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* Created by wzh-zhua on 2020/3/29.
*/
public class TlsCompatSocketFactory extends SSLSocketFactory {
private static final String[] TLS_VERSION_LIST = {"TLSv1", "TLSv1.1", "TLSv1.2"};
private final SSLSocketFactory target;
public TlsCompatSocketFactory(SSLSocketFactory target) {
this.target = target;
}
@Override
public String[] getDefaultCipherSuites() {
return target.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return target.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return supportTLS(target.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return supportTLS(target.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return supportTLS(target.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return supportTLS(target.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return supportTLS(target.createSocket(address, port, localAddress, localPort));
}
private Socket supportTLS(Socket s) {
if (s instanceof SSLSocket) {
((SSLSocket) s).setEnabledProtocols(TLS_VERSION_LIST);
}
return s;
}
}