最近搞一个消息推送的项目,使用的是极光的推送服务,自己写了一个HTTPS请求工具类,在Windows下部署都正常运行,在eclipse下的运行也是正常的,部署到Linux的服务器上,请求HTTPS时一直报链接重置(java.net.SocketException: Connection reset),网上各种找都没有解决 ,期间还停了好久。后来不小心看到一个参数‘java.protocol.handler.pkgs’,好像有点希望的样子,果断试一下,还真行了。System.setProperty("java.protocol.handler.pkgs", "javax.net.ssl");
代码如下:
package com.amway.message.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
/**
* Created by fulunyong on 2017/3/31 15:53
*
* @email [email protected]
*/
public final class HttpsUtil {
private static String defaultContentEncoding = "UTF-8";
// 连接主机超时(30s)
private static final int HTTP_CONNECT_TIMEOUT_30S = 30 * 1000;
// 从主机读取数据超时(3min)
private static final int HTTP_READ_TIMEOUT_3MIN = 180 * 1000;
private static Logger logger = Logger.getLogger(HttpsUtil.class);
/**
* 获取第一个请求IP地址
*
* @param request
* 请求
* @return 外网IP
*/
public static String getFistRemoteAddress(HttpServletRequest request) {
String remoteAddress = getRemoteAddress(request);
String[] split = remoteAddress.split(",");
if (1 < split.length) {
remoteAddress = split[0];// 多个地址,只获取第一个 第一为真正请求的外网IP,其后的为代理IP。
}
return remoteAddress;
}
/**
* 获取请求IP
*
* @param request
* 请求
* @return IP
*/
private static String getRemoteAddress(HttpServletRequest request) {
String remoteAddress = request.getHeader("X-Real-IP");
if (StringUtils.isNotBlank(remoteAddress)) {
remoteAddress = request.getHeader("X-Forwarded-For");
} else if (StringUtils.isNotBlank(remoteAddress)) {
remoteAddress = request.getHeader("Proxy-Client-IP");
} else if (StringUtils.isNotBlank(remoteAddress)) {
remoteAddress = request.getHeader("WL-Proxy-Client-IP");
}
return remoteAddress != null ? remoteAddress : request.getRemoteAddr();
}
public static String postJson(String urlStr, Map
return postJson(urlStr, new HashMap
}
public static String postJson(String urlStr, Map
return postJson(urlStr, header, param, defaultContentEncoding);
}
public static String postJson(String urlStr, Map
return postJson(urlStr, new HashMap
}
public static String postJson(String urlStr, Map
String charset) {
return json(urlStr, header, param, charset, "POST");
}
public static String getJson(String urlStr) {
return getJson(urlStr, null);
}
public static String getJson(String urlStr, Map
return getJson(urlStr, header, null);
}
public static String getJson(String urlStr, Map
return getJson(urlStr, header, param, defaultContentEncoding);
}
public static String getJson(String urlStr, Map
return json(urlStr, header, param, charset, "GET");
}
public static String putJson(String urlStr, Map
return putJson(urlStr, header, param, defaultContentEncoding);
}
public static String putJson(String urlStr, Map
return json(urlStr, header, param, charset, "PUT");
}
public static String deleteJson(String urlStr, Map
return deleteJson(urlStr, header, param, defaultContentEncoding);
}
public static String deleteJson(String urlStr, Map
String charset) {
return json(urlStr, header, param, charset, "DELETE");
}
private static String json(String urlStr, Map
String method) {
if (StringUtils.startsWith(urlStr, "https")) {
return httpsJson(urlStr, header, param, charset, method);
}
String result = null;
HttpURLConnection urlConnection = null;
InputStream inStream = null;
logger.info("request url :" + urlStr);
logger.info("request method :" + method);
try {
URL url = new URL(urlStr);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
urlConnection.setConnectTimeout(HTTP_CONNECT_TIMEOUT_30S);
urlConnection.setReadTimeout(HTTP_READ_TIMEOUT_3MIN);
urlConnection.setRequestMethod(method);
urlConnection.setRequestProperty("charset", charset);
urlConnection.setRequestProperty("Content-Type", "application/json");
// header 参数设置
if (null != header && 0 < header.size()) {
Set
for (Map.Entry
urlConnection.setRequestProperty(entry.getKey(), entry.getValue());
}
}
if (null == param) {
param = new HashMap
}
String jsonString = JSONUtils.toString(param);
if (StringUtils.isNotEmpty(jsonString)) {
OutputStream outputStream = urlConnection.getOutputStream();
byte[] bytes = jsonString.getBytes(charset);
logger.info(String.format("send data length:%d", bytes.length));
outputStream.write(bytes);
outputStream.flush();
outputStream.close();
}
int responseCode = urlConnection.getResponseCode();
InputStream inputStream;
if (HttpURLConnection.HTTP_OK == responseCode) {
inputStream = urlConnection.getInputStream();
} else {
logger.error("responseCode error responseCode=" + responseCode);
logger.error("response = " + IOUtils.toString(urlConnection.getErrorStream(), charset));
System.err.println("System.err responseCode error responseCode=" + responseCode);
System.err.println("System.err response = " + IOUtils.toString(urlConnection.getErrorStream(), charset));
return null;
}
String encoding = urlConnection.getContentEncoding();
if (StringUtils.isNotEmpty(encoding)) {
if (encoding.contains("gzip")) {
// 如果支持则应该使用GZIPInputStream解压,否则会出现乱码无效数据
inputStream = new GZIPInputStream(inputStream);
}
}
result = IOUtils.toString(inputStream, charset);
} catch (Exception e) {
e.printStackTrace();
logger.error("postJson throw exception:", e);
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException e) {
logger.error(urlStr + " Error", e);
}
}
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return result;
}
private static String httpsJson(String urlStr, Map
String charset, String method) {
String result = null;
HttpsURLConnection httpsURLConnection = null;
InputStream inStream = null;
logger.info("request https url :" + urlStr);
logger.info("request https method :" + method);
try {
//指定SSL参数
System.setProperty("java.protocol.handler.pkgs", "javax.net.ssl");
URL url = new URL(urlStr);
httpsURLConnection = (HttpsURLConnection) url.openConnection();
httpsURLConnection.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
logger.info("verify: URL Host: " + hostname + " vs. " +
session.getPeerHost());
return true;
}
});
SSLContext sslContext = SSLContext.getInstance("TLSv1");
sslContext.init(new KeyManager[0], new TrustManager[]{new miTM()}, new SecureRandom());
SSLContext.setDefault(sslContext);
System.err.println("sslContext=getProtocol="+sslContext.getProtocol());
System.err.println("sslContext=getSupportedSSLParameters="+JSONUtils.toString(sslContext.getSupportedSSLParameters()));
System.err.println("sslContext=getProvider="+sslContext.getProvider());
httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
httpsURLConnection.setDoInput(true);
httpsURLConnection.setDoOutput(true);
httpsURLConnection.setUseCaches(false);
httpsURLConnection.setConnectTimeout(HTTP_CONNECT_TIMEOUT_30S);
httpsURLConnection.setReadTimeout(HTTP_READ_TIMEOUT_3MIN);
httpsURLConnection.setRequestMethod(method);
httpsURLConnection.setRequestProperty("accept", "*/*");
httpsURLConnection.setRequestProperty("connection", "Keep-Alive");
httpsURLConnection.setRequestProperty("charset", charset);
httpsURLConnection.setRequestProperty("Content-Type", "application/json");
// header 参数设置
if (null != header && 0 < header.size()) {
Set
for (Map.Entry
httpsURLConnection.setRequestProperty(entry.getKey(), entry.getValue());
}
}
if (null == param) {
param = new HashMap
}
String jsonString = JSONUtils.toString(param);
if (StringUtils.isNotEmpty(jsonString)) {
OutputStream outputStream = httpsURLConnection.getOutputStream();
byte[] bytes = jsonString.getBytes(charset);
logger.info(String.format("send data length:%d", bytes.length));
outputStream.write(bytes);
outputStream.flush();
outputStream.close();
}
int responseCode = httpsURLConnection.getResponseCode();
logger.info("<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>responseCode="+responseCode);
InputStream inputStream;
if (HttpsURLConnection.HTTP_OK == responseCode) {
inputStream = httpsURLConnection.getInputStream();
} else {
logger.error("responseCode error responseCode=" + responseCode);
logger.error("response = " + IOUtils.toString(httpsURLConnection.getErrorStream(), charset));
System.err.println("System.err responseCode error responseCode=" + responseCode);
System.err.println("System.err response = " + IOUtils.toString(httpsURLConnection.getErrorStream(), charset));
return null;
}
String encoding = httpsURLConnection.getContentEncoding();
if (StringUtils.isNotEmpty(encoding)) {
if (encoding.contains("gzip")) {
// 如果支持则应该使用GZIPInputStream解压,否则会出现乱码无效数据
inputStream = new GZIPInputStream(inputStream);
}
}
result = IOUtils.toString(inputStream, charset);
} catch (Exception e) {
e.printStackTrace();
System.err.println("postJson throw exception:"+e.getLocalizedMessage());
logger.error("postJson throw exception:", e);
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException e) {
logger.error(urlStr + " Error", e);
}
}
if (httpsURLConnection != null) {
httpsURLConnection.disconnect();
}
}
return result;
}
static class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
}
}