需求:我的请求是https,但是有时候证书会过期,此时此时请求就会报错
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
有两种方案:
方案一:更新https的证书
方案二:https请求忽略ssl证书校验
接下来着重讲方案二
直接上代码 自己平时汇总的最好的http的工具类,没有之一
/**
* JSON请求发起 Post
*
* @param requestUrl 请求地址
* @param requestJson 请求报文(JSON格式)
* @param timeout 超时时间(毫秒)
* @return
* @throws Exception
*/
public static String httpJsonRequestPost(String requestUrl, String requestJson, int timeout) throws Exception {
String responseJson = "";
try {
URL url = new URL(requestUrl);
// 忽略ssl证书校验
SSLUtil.disableSSLVerification();
// 打开和url之间的连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
PrintWriter out = null;
// 请求方式
conn.setRequestMethod("POST");
// //设置通用的请求属性
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
conn.setRequestProperty("accept", "*/*");
conn.setDoOutput(true);// 设置是否向connection输出,因为这个是post请求,参数要放在http正文内,因此需要设为true,默认情况下是false
conn.setDoInput(true); // 设置是否从connection读入,默认情况下是true;
conn.setRequestMethod("POST");// 设置请求方式为post,默认GET请求
conn.setUseCaches(false);// post请求不能使用缓存设为false
conn.setConnectTimeout(timeout);// 连接主机的超时时间
conn.setReadTimeout(timeout);// 从主机读取数据的超时时间
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// 设置是否向httpUrlConnection输出,设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个
// 最常用的Http请求无非是get和post,get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,
// post与get的 不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数即数据
out.print(requestJson);
// 缓冲数据
out.flush();
// 获取URLConnection对象对应的输入流
InputStream is = conn.getInputStream();
// 构造一个字符流缓存
BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
StringBuilder result = new StringBuilder();
String le;
while ((le = br.readLine()) != null) {
result.append(le);
}
responseJson = result.toString();
// 关闭流
is.close();
// 断开连接,最好写上,disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
// 固定多线程的话,如果不disconnect,链接会增多,直到收发不出信息。写上disconnect后正常一些。
conn.disconnect();
} catch (Exception e) {
throw e;
}
return responseJson;
}
接下来上ssl工具类
import javax.net.ssl.*;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
public class SSLUtil {
public static void disableSSLVerification() {
try {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = (hostname, session) -> true;
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (Exception e) {
e.printStackTrace();
}
}
}