Java Https工具类,Java Https Post请求
================================
©Copyright 蕃薯耀 2019-01-08
http://fanshuyao.iteye.com/
一、使用jsoup进行连接
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.X509TrustManager; import org.jsoup.Connection; import org.jsoup.Connection.Response; import org.jsoup.Jsoup; public class HttpsUtils { /** * 请求超时时间 */ private static final int TIME_OUT = 120000; /** * Https请求 */ private static final String HTTPS = "https"; /** * 返回成功状态码 */ private static final int OK = 200; /** * 纯字符串参数post请求 * * @param url 请求URL地址 * @param paramMap 请求字符串参数集合 * @return 服务器返回内容 * @throws Exception */ public static String post(String url, MapparamMap) throws Exception { Response response = doPostRequest(url, paramMap, null); return response.body(); } /** * 带上传文件的post请求 * * @param url 请求URL地址 * @param paramMap 请求字符串参数集合 * @param fileMap 请求文件参数集合 * @return 服务器返回内容 * @throws Exception */ public static String post(String url, Map paramMap, Map fileMap) throws Exception { Response response = doPostRequest(url, paramMap, fileMap); return response.body(); } /** * 执行post请求 * * @param url 请求URL地址 * @param paramMap 请求字符串参数集合 * @param fileMap 请求文件参数集合 * @return 服务器相应对象 * @throws Exception */ public static Response doPostRequest(String url, Map paramMap, Map fileMap) throws Exception { if (null == url || url.isEmpty()) { throw new Exception("The request URL is blank."); } // 如果是Https请求 if (url.startsWith(HTTPS)) { getTrust(); } Connection connection = Jsoup.connect(url); //Connection connection = Jsoup.connect(url).url(new URL(null, url, new sun.net.www.protocol.https.Handler()));//可用 connection.method(Connection.Method.POST); connection.timeout(TIME_OUT); connection.header("Content-Type", "multipart/form-data"); connection.ignoreHttpErrors(true); connection.ignoreContentType(true); // 添加字符串类参数 if (null != paramMap && !paramMap.isEmpty()) { connection.data(paramMap); } // 添加文件参数 if (null != fileMap && !fileMap.isEmpty()) { InputStream in = null; File file = null; Set > set = fileMap.entrySet(); try { for (Entry e : set) { file = e.getValue(); in = new FileInputStream(file); connection.data(e.getKey(), file.getName(), in); } } catch (FileNotFoundException e) { throw new Exception(e.getMessage()); } } try { Response response = connection.execute(); if (response.statusCode() != OK) { throw new Exception(response.statusMessage()); } return response; } catch (IOException e) { throw new Exception(e); } } /** * 获取服务器信任 */ private static void getTrust() { try { HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); SSLContext context = SSLContext.getInstance("TLS"); context.init(null, new X509TrustManager[] { new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {} public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {} public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } }, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); } catch (Exception e) { e.printStackTrace(); } } }
在可以连接互联网的时候没有问题,但在公司内网,访问不到互联网,只能访问某些接口时会出错,如下:
java.lang.Exception: javax.net.ssl.SSLKeyException: FATAL Alert:BAD_CERTIFICATE - A corrupt or unuseable certificate was received.
发现这个问题主要是Connection连接的问题。
如果修改Connection连接如下就可正常访问:
Connection connection = Jsoup.connect(url).url(new URL(null, url, new sun.net.www.protocol.https.Handler()));
或者:
Connection connection = Jsoup.connect(url).url(new URL(null, url, new sun.net.www.protocol.https.Handler())).validateTLSCertificates(false);
使用代理(未测试):
Connection connection = Jsoup.connect(url).url(new URL(null, url, new sun.net.www.protocol.https.Handler())).userAgent("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
二、使用原生的HttpURLConnection连接
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.security.cert.CertificateException; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.security.cert.X509Certificate; public class HttpsClientUtil { private final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; private static void trustAllHosts() { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[]{}; } public void checkClientTrusted(X509Certificate[] chain, String authType) { } public void checkServerTrusted(X509Certificate[] chain, String authType) { } @Override public void checkClientTrusted( java.security.cert.X509Certificate[] arg0, String arg1) throws CertificateException { // TODO Auto-generated method stub } @Override public void checkServerTrusted( java.security.cert.X509Certificate[] arg0, String arg1) throws CertificateException { // TODO Auto-generated method stub } }}; // Install the all-trusting trust manager try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { e.printStackTrace(); } } public static String sendHtpps(String a,String url) { String result = ""; OutputStreamWriter out = null; BufferedReader in = null; HttpURLConnection conn; try { trustAllHosts(); URL realUrl = new URL(null,url,new sun.net.www.protocol.https.Handler()); //通过请求地址判断请求类型(http或者是https) if (realUrl.getProtocol().toLowerCase().equals("https")) { HttpsURLConnection https = (HttpsURLConnection) realUrl.openConnection(); https.setHostnameVerifier(DO_NOT_VERIFY); conn = https; } else { conn = (HttpURLConnection) realUrl.openConnection(); } // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); out.write(a); //错误方式,这种方式容易出现乱码 // PrintWriter out = new PrintWriter(connection.getOutputStream()); /*out.print(a);*/ // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader( new InputStreamReader(conn.getInputStream(), "UTF-8")); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { result = "sendHtpps error"; e.printStackTrace(); } finally {// 使用finally块来关闭输出流、输入流 try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result; } }
github两个比较好的Http请求工具,支持Https
1、https://github.com/kevinsawicki/http-request
com.github.kevinsawicki http-request 6.0
2、https://github.com/hsiafan/requests
net.dongliu requests 5.0.3
================================
©Copyright 蕃薯耀 2019-01-08
http://fanshuyao.iteye.com/