最近搞一个消息推送的项目,使用的是极光的推送服务,自己写了一个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 fulunyong@126.com
 */
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<String, Object> param) {
return postJson(urlStr, new HashMap<String, String>(), param);
}


public static String postJson(String urlStr, Map<String, String> header, Map<String, Object> param) {
return postJson(urlStr, header, param, defaultContentEncoding);
}


public static String postJson(String urlStr, Map<String, Object> param, String charset) {
return postJson(urlStr, new HashMap<String, String>(), param, charset);
}


public static String postJson(String urlStr, Map<String, String> header, Map<String, Object> param,
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<String, String> header) {
return getJson(urlStr, header, null);
}


public static String getJson(String urlStr, Map<String, String> header, Map<String, Object> param) {
return getJson(urlStr, header, param, defaultContentEncoding);
}


public static String getJson(String urlStr, Map<String, String> header, Map<String, Object> param, String charset) {
return json(urlStr, header, param, charset, "GET");
}


public static String putJson(String urlStr, Map<String, String> header, Map<String, Object> param) {
return putJson(urlStr, header, param, defaultContentEncoding);
}


public static String putJson(String urlStr, Map<String, String> header, Map<String, Object> param, String charset) {
return json(urlStr, header, param, charset, "PUT");
}


public static String deleteJson(String urlStr, Map<String, String> header, Map<String, Object> param) {
return deleteJson(urlStr, header, param, defaultContentEncoding);
}


public static String deleteJson(String urlStr, Map<String, String> header, Map<String, Object> param,
String charset) {
return json(urlStr, header, param, charset, "DELETE");
}


private static String json(String urlStr, Map<String, String> header, Map<String, Object> param, String charset,
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<Map.Entry<String, String>> entrySet = header.entrySet();
for (Map.Entry<String, String> entry : entrySet) {
urlConnection.setRequestProperty(entry.getKey(), entry.getValue());
}
}
if (null == param) {
param = new HashMap<String, Object>();
}
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, String> header, Map<String, Object> param,
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<Map.Entry<String, String>> entrySet = header.entrySet();
for (Map.Entry<String, String> entry : entrySet) {
httpsURLConnection.setRequestProperty(entry.getKey(), entry.getValue());
}
}

if (null == param) {
param = new HashMap<String, Object>();
}
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;
}
}


}

Logo

更多推荐