You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
451 lines
13 KiB
451 lines
13 KiB
package com.fr.plugin.third.party.jsdjjed.util.http; |
|
|
|
import javax.net.ssl.*; |
|
import java.io.*; |
|
import java.net.*; |
|
import java.security.*; |
|
import java.security.cert.CertificateException; |
|
import java.security.cert.X509Certificate; |
|
import java.util.ArrayList; |
|
import java.util.HashMap; |
|
import java.util.List; |
|
import java.util.Map; |
|
import java.util.Map.Entry; |
|
|
|
/** |
|
* @Author xx |
|
* @Date 2020/9/15 |
|
* @Description |
|
**/ |
|
public class HttpClient { |
|
|
|
/** |
|
* 链接超时时间(s) |
|
*/ |
|
private int httpConnectionTimeOut = 30; |
|
|
|
/** |
|
* 数据传输超时时间(s) |
|
*/ |
|
private int httpReadTimeOut = 30; |
|
|
|
public HttpClient() { |
|
|
|
} |
|
|
|
/** |
|
* |
|
* @param httpConnectionTimeOut |
|
* 链接超时时间(s) |
|
* @param httpReadTimeOut |
|
* 数据传输超时时间(s) |
|
*/ |
|
public HttpClient(int httpConnectionTimeOut, int httpReadTimeOut) { |
|
this.httpConnectionTimeOut = httpConnectionTimeOut; |
|
this.httpReadTimeOut = httpReadTimeOut; |
|
} |
|
|
|
/** |
|
* 发送HTTP请求 |
|
* |
|
* @param request |
|
* 请求 |
|
* @param praser |
|
* 响应解析器 |
|
* @return T 响应 |
|
*/ |
|
public <T> T service(HttpRequest<?> request, HttpResponsePraser<T> praser) { |
|
HttpResultCode code = HttpResultCode.SUCCESS; |
|
if (request.getHttpParams().getUrl() == null || request.getHttpParams().getUrl().length() == 0) { |
|
code = HttpResultCode.ERROR_URL_NULL; |
|
return praser.prase(code, 0, null, null, request.getHttpParams().getCharSet(), null); |
|
} |
|
HttpURLConnection conn = null; |
|
int httpCode = 0; |
|
Map<String, String> headers = null; |
|
List<String> cookies = null; |
|
ByteArrayOutputStream outputStream = null; |
|
try { |
|
String realUrl = this.genUrl(request); |
|
conn = this.createConnection(request, realUrl); |
|
this.fillConnection(conn, request); |
|
this.request(conn, request); |
|
httpCode = conn.getResponseCode(); |
|
headers = this.getHeaders(conn, request.getHttpParams().getCharSet()); |
|
cookies = this.getCookies(conn, request.getHttpParams().getCharSet()); |
|
outputStream = this.getResultOutputStream(conn); |
|
} catch (SocketTimeoutException e) { |
|
code = HttpResultCode.ERROR_TIMEOUT; |
|
e.printStackTrace(); |
|
} catch (KeyManagementException e) { |
|
code = HttpResultCode.ERROR_HTTPS_SSL; |
|
e.printStackTrace(); |
|
} catch (NoSuchAlgorithmException e) { |
|
code = HttpResultCode.ERROR_HTTPS_SSL; |
|
e.printStackTrace(); |
|
} catch (ProtocolException e) { |
|
code = HttpResultCode.ERROR_METHOD; |
|
e.printStackTrace(); |
|
} catch (UnsupportedEncodingException e) { |
|
code = HttpResultCode.ERROR_CHARSET; |
|
e.printStackTrace(); |
|
} catch (MalformedURLException e) { |
|
code = HttpResultCode.ERROR_URL; |
|
httpCode = 500; |
|
e.printStackTrace(); |
|
} catch (IOException e) { |
|
code = HttpResultCode.ERROR_CONNECT; |
|
e.printStackTrace(); |
|
} catch (UnrecoverableKeyException e) { |
|
code = HttpResultCode.ERROR_HTTPS_SSL; |
|
e.printStackTrace(); |
|
} catch (KeyStoreException e) { |
|
code = HttpResultCode.ERROR_HTTPS_SSL; |
|
e.printStackTrace(); |
|
} catch (CertificateException e) { |
|
code = HttpResultCode.ERROR_HTTPS_SSL; |
|
e.printStackTrace(); |
|
} finally { |
|
if (conn != null) { |
|
conn.disconnect(); |
|
} |
|
} |
|
T t = null; |
|
try { |
|
t = praser.prase(code, httpCode, headers, cookies, request.getHttpParams().getCharSet(), outputStream); |
|
} catch (Exception e) { |
|
e.printStackTrace(); |
|
} finally { |
|
if (outputStream != null) { |
|
try { |
|
outputStream.flush(); |
|
outputStream.close(); |
|
} catch (IOException e) { |
|
e.printStackTrace(); |
|
} |
|
} |
|
} |
|
return t; |
|
} |
|
|
|
private <T> String genUrl(HttpRequest<T> request) { |
|
if (request.getHttpParams().getMethod().equalsIgnoreCase("GET")) { |
|
String getprams = request.getContentPraser().praseRqeuestContentToString(request.getHttpParams()); |
|
if (getprams != null) { |
|
String url = null; |
|
if (request.getHttpParams().getUrl().indexOf("?") > 0) { |
|
url = request.getHttpParams().getUrl() + "&" + getprams; |
|
} else { |
|
url = request.getHttpParams().getUrl() + "?" + getprams; |
|
} |
|
return url; |
|
} else { |
|
return request.getHttpParams().getUrl(); |
|
} |
|
} else { |
|
return request.getHttpParams().getUrl(); |
|
} |
|
} |
|
|
|
/** |
|
* 获取HTTP响应头 |
|
* |
|
* @param conn |
|
* @param charSet |
|
* @return |
|
* @throws UnsupportedEncodingException |
|
*/ |
|
private Map<String, String> getHeaders(HttpURLConnection conn, String charSet) throws UnsupportedEncodingException { |
|
Map<String, String> resultHeaders = new HashMap<String, String>(); |
|
Map<String, List<String>> header = conn.getHeaderFields(); |
|
if (header != null && header.size() > 0) { |
|
for (Entry<String, List<String>> entry : header.entrySet()) { |
|
if (!"Set-Cookie".equalsIgnoreCase(entry.getKey())) { |
|
String valuer = ""; |
|
if (entry.getValue() != null && entry.getValue().size() > 0) { |
|
for (String value : entry.getValue()) { |
|
valuer += new String(value.getBytes("ISO-8859-1"), charSet) + ","; |
|
} |
|
valuer = valuer.substring(0, valuer.length() - 1); |
|
} |
|
resultHeaders.put(entry.getKey(), valuer); |
|
} |
|
} |
|
} |
|
return resultHeaders; |
|
} |
|
|
|
/** |
|
* 获取HTTP响应Cookies |
|
* |
|
* @param conn |
|
* @param charSet |
|
* @return |
|
* @throws UnsupportedEncodingException |
|
*/ |
|
private List<String> getCookies(HttpURLConnection conn, String charSet) throws UnsupportedEncodingException { |
|
List<String> resultC = new ArrayList<String>(); |
|
List<String> cookies = null; |
|
Map<String, List<String>> header = conn.getHeaderFields(); |
|
if (header != null && header.size() > 0) { |
|
cookies = header.get("Set-Cookie"); |
|
} |
|
if (cookies != null) { |
|
for (String cookie : cookies) { |
|
resultC.add(new String(cookie.getBytes("ISO-8859-1"), charSet)); |
|
} |
|
} |
|
return cookies; |
|
} |
|
|
|
/** |
|
* 获取HTTP响应数据流 |
|
* |
|
* @param conn |
|
* @return |
|
* @throws IOException |
|
*/ |
|
private ByteArrayOutputStream getResultOutputStream(HttpURLConnection conn) throws IOException { |
|
ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
|
InputStream is = conn.getInputStream(); |
|
try { |
|
if (is != null) { |
|
byte[] buffer = new byte[1024]; |
|
int len = 0; |
|
while ((len = is.read(buffer)) != -1) { |
|
outStream.write(buffer, 0, len); |
|
} |
|
} |
|
} catch (IOException e) { |
|
throw e; |
|
} finally { |
|
if (is != null) { |
|
is.close(); |
|
} |
|
} |
|
return outStream; |
|
} |
|
|
|
/** |
|
* 发送Http请求 |
|
* |
|
* @param conn |
|
* @param request |
|
* @throws IOException |
|
*/ |
|
private <T> void request(HttpURLConnection conn, HttpRequest<T> request) throws IOException { |
|
if (request.getHttpParams().getMethod().equalsIgnoreCase("POST")) { |
|
conn.setDoOutput(true); |
|
// conn.connect(); |
|
if (request.getHttpParams().getParams() != null) { |
|
byte[] content = request.getContentPraser().praseRqeuestContentToBytes(request.getHttpParams()); |
|
fillHeader(conn, "Content-Length", String.valueOf(request.getContentPraser().praseRqeuestContentLength(request.getHttpParams()))); |
|
DataOutputStream out = new DataOutputStream(conn.getOutputStream()); |
|
out.write(content); |
|
out.flush(); |
|
out.close(); |
|
} |
|
} else { |
|
conn.connect(); |
|
} |
|
} |
|
|
|
/** |
|
* 添加请求信息 |
|
* |
|
* @param conn |
|
* @param request |
|
* @throws ProtocolException |
|
*/ |
|
private void fillConnection(HttpURLConnection conn, HttpRequest<?> request) throws ProtocolException { |
|
this.fillTimeout(conn); |
|
this.filleMethod(conn, request); |
|
this.fillHeaders(conn, request); |
|
this.fillCookies(conn, request); |
|
} |
|
|
|
/** |
|
* 添加超时时间 |
|
* |
|
* @param conn |
|
*/ |
|
private void fillTimeout(HttpURLConnection conn) { |
|
if (httpConnectionTimeOut != 0) { |
|
conn.setConnectTimeout(httpConnectionTimeOut * 1000); |
|
} |
|
if (httpReadTimeOut != 0) { |
|
conn.setReadTimeout(httpReadTimeOut * 1000); |
|
} |
|
} |
|
|
|
/** |
|
* 指定HTTP方法 |
|
* |
|
* @param conn |
|
* @param request |
|
* @throws ProtocolException |
|
*/ |
|
private void filleMethod(HttpURLConnection conn, HttpRequest<?> request) throws ProtocolException { |
|
conn.setRequestMethod(request.getHttpParams().getMethod().toUpperCase()); |
|
} |
|
|
|
/** |
|
* 添加头信息 |
|
* |
|
* @param conn |
|
* @param request |
|
*/ |
|
private void fillHeaders(HttpURLConnection conn, HttpRequest<?> request) { |
|
if (request.getHttpParams().getHeaders() != null) { |
|
for (Entry<String, String> entry : request.getHttpParams().getHeaders().entrySet()) { |
|
fillHeader(conn, entry.getKey(), entry.getValue()); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* 添加头信息 |
|
* |
|
* @param conn |
|
* @param request |
|
*/ |
|
private void fillHeader(HttpURLConnection conn, String key, String value) { |
|
conn.setRequestProperty(key, value); |
|
} |
|
|
|
/** |
|
* 添加Cookies |
|
* |
|
* @param conn |
|
* @param request |
|
*/ |
|
private void fillCookies(HttpURLConnection conn, HttpRequest<?> request) { |
|
if (request.getHttpParams().getCookies() != null) { |
|
conn.setRequestProperty("Cookie", request.getHttpParams().getCookies()); |
|
} |
|
} |
|
|
|
/** |
|
* 创建Http链接 |
|
* |
|
* @param request |
|
* @return |
|
* @throws NoSuchAlgorithmException |
|
* @throws KeyManagementException |
|
* @throws MalformedURLException |
|
* @throws IOException |
|
* @throws CertificateException |
|
* @throws KeyStoreException |
|
* @throws UnrecoverableKeyException |
|
*/ |
|
private HttpURLConnection createConnection(HttpRequest<?> request, String realUrl) |
|
throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException, IOException, UnrecoverableKeyException, KeyStoreException, CertificateException { |
|
URL console = new URL(realUrl); |
|
HttpURLConnection conn; |
|
if (request.isHttps()) { |
|
conn = genHttpsConn(console, request); |
|
} else { |
|
conn = (HttpURLConnection) console.openConnection(); |
|
} |
|
return conn; |
|
} |
|
|
|
private HttpURLConnection genHttpsConn(URL console, HttpRequest<?> request) |
|
throws UnrecoverableKeyException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { |
|
SSLContext ctx = getSSLContext(request.getHttpsParams()); |
|
HttpsURLConnection sconn = (HttpsURLConnection) console.openConnection(); |
|
sconn.setSSLSocketFactory(ctx.getSocketFactory()); |
|
sconn.setHostnameVerifier(new HostnameVerifier() { |
|
public boolean verify(String hostname, SSLSession session) { |
|
return true; |
|
} |
|
}); |
|
return sconn; |
|
} |
|
|
|
/** |
|
* 获得KeyStore. |
|
* |
|
* @param keyStorePath |
|
* 密钥库路径 |
|
* @param password |
|
* 密码 |
|
* @return 密钥库 |
|
* @throws KeyStoreException |
|
* @throws IOException |
|
* @throws CertificateException |
|
* @throws NoSuchAlgorithmException |
|
* @throws Exception |
|
*/ |
|
private KeyStore getKeyStore(HttpsParams params) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { |
|
// 实例化密钥库 KeyStore用于存放证书,创建对象时 指定交换数字证书的加密标准 |
|
// 指定交换数字证书的加密标准 |
|
KeyStore ks = KeyStore.getInstance(params.getAlgorithm()); |
|
// 获得密钥库文件流 |
|
FileInputStream is = new FileInputStream(params.getKeyStorePath()); |
|
// 加载密钥库 |
|
ks.load(is, params.getPassword().toCharArray()); |
|
// 关闭密钥库文件流 |
|
is.close(); |
|
return ks; |
|
} |
|
|
|
/** |
|
* 获得SSLSocketFactory. |
|
* |
|
* @param password |
|
* 密码 |
|
* @param keyStorePath |
|
* 密钥库路径 |
|
* @param trustStorePath |
|
* 信任库路径 |
|
* @return SSLSocketFactory |
|
* @throws NoSuchAlgorithmException |
|
* @throws IOException |
|
* @throws CertificateException |
|
* @throws KeyStoreException |
|
* @throws UnrecoverableKeyException |
|
* @throws KeyManagementException |
|
* @throws Exception |
|
*/ |
|
private SSLContext getSSLContext(HttpsParams params) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException, KeyManagementException { |
|
// 实例化SSL上下文 |
|
SSLContext ctx = SSLContext.getInstance("TLS"); |
|
if (params != null) { |
|
// 实例化密钥库 KeyManager选择证书证明自己的身份 |
|
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); |
|
// 实例化信任库 TrustManager决定是否信任对方的证书 |
|
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); |
|
// 获得密钥库 |
|
KeyStore keyStore = getKeyStore(params); |
|
// 初始化密钥工厂 |
|
keyManagerFactory.init(keyStore, params.getPassword().toCharArray()); |
|
// 获得信任库 |
|
KeyStore trustStore = getKeyStore(params); |
|
// 初始化信任库 |
|
trustManagerFactory.init(trustStore); |
|
// 初始化SSL上下文 |
|
ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); |
|
} else { |
|
ctx.init(null, new TrustManager[] { myX509TrustManager }, new SecureRandom()); |
|
} |
|
return ctx; |
|
} |
|
|
|
private TrustManager myX509TrustManager = new X509TrustManager() { |
|
|
|
@Override |
|
public X509Certificate[] getAcceptedIssuers() { |
|
return null; |
|
} |
|
|
|
@Override |
|
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { |
|
} |
|
|
|
@Override |
|
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { |
|
} |
|
}; |
|
|
|
}
|
|
|