<a name='RestfulHttpClient.java'></a> RestfulHttpClient.javahtml
package pres.lnk.utils; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.StringUtils; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * <p>RestfulApi請求工具</p> * <a href="http://blog.csdn.net/lnktoking/article/details/79174187">使用說明</a> * * @author lnk */ public class RestfulHttpClient { /** * 全局默認請求頭 */ private static final Map<String, String> defaultHeaders = new HashMap<>(); /** * 全局鏈接初始化器 */ private static List<URLConnectionInitializer> initializers; private static final String charset = "UTF-8"; private static final int readTimeout = 60000; private static final int connectTimeout = 60000; public static final String METHOD_GET = "GET"; public static final String METHOD_POST = "POST"; public static final String METHOD_PUT = "PUT"; public static final String METHOD_PATCH = "PATCH"; public static final String METHOD_DELETE = "DELETE"; private RestfulHttpClient() { } /** * 發起請求 * * @param method 請求方式:GET、POST、PUT、PATCH、DELETE * @param url 請求url * @param body 請求體body * @throws IOException */ public static HttpResponse request(String method, String url, Object body) throws IOException { return request(method, url, body, defaultHeaders); } /** * 發起請求 * * @param method 請求方式:GET、POST、PUT、PATCH、DELETE * @param url 請求url * @param body 請求體body * @param headers 請求頭 * @throws IOException */ public static HttpResponse request(String method, String url, Object body, Map<String, String> headers) throws IOException { return getClient(url).method(method).body(body).headers(headers).request(); } /** * 獲取請求客戶端 * * @param url * @return */ public static HttpClient getClient(String url) { return new HttpClient(url); } /** * 添加全局請求鏈接初始化器 * * @param initializer */ public static void addInitializer(URLConnectionInitializer initializer) { if (initializer == null) { throw new NullPointerException("不能添加空的鏈接初始化器"); } if (initializers == null) { initializers = new ArrayList<>(); } initializers.add(initializer); } /** * 請求客戶端 */ public static class HttpClient { private Map<String, String> headers; private int readTimeout = RestfulHttpClient.readTimeout; private int connectTimeout = RestfulHttpClient.connectTimeout; private String method = METHOD_GET; private String url; private Map<String, String> pathParams; private Map<String, String> queryParams; private Map<String, String> postParams; private Object body; private HttpResponse response; private List<URLConnectionInitializer> initializers; public HttpClient(String url) { if (StringUtils.isBlank(url)) { throw new IllegalArgumentException("請求地址不能爲空"); } this.url = url; headers = new HashMap<>(); pathParams = new HashMap<>(); queryParams = new HashMap<>(); postParams = new HashMap<>(); headers.putAll(defaultHeaders); initializers = RestfulHttpClient.initializers; } public HttpClient get() { method = METHOD_GET; return this; } public HttpClient post() { method = METHOD_POST; return this; } public HttpClient put() { method = METHOD_PUT; return this; } public HttpClient patch() { method = METHOD_PATCH; return this; } public HttpClient delete() { method = METHOD_DELETE; return this; } /** * 添加請求頭 */ public HttpClient addHeader(String key, String value) { this.headers.put(key, value); return this; } /** * 批量添加請求頭 */ public HttpClient addHeaders(Map<String, String> headers) { this.headers.putAll(headers); return this; } /** * 設置讀取超時時間 */ public HttpClient readTimeout(int readTimeout) { this.readTimeout = readTimeout; return this; } /** * 設置鏈接超時時間 */ public HttpClient connectTimeout(int connectTimeout) { this.connectTimeout = connectTimeout; return this; } /** * 重置請求頭 */ public HttpClient headers(Map<String, String> headers) { this.headers.clear(); this.headers.putAll(defaultHeaders); return addHeaders(headers); } /** * 設置請求方式,默認:GET */ public HttpClient method(String method) { if (StringUtils.isBlank(method)) { throw new IllegalArgumentException("請求方式不能爲空"); } //請求方式不作限制 // if(!ArrayUtils.contains(new String[]{METHOD_GET, METHOD_POST, METHOD_PUT, METHOD_PATCH, METHOD_DELETE}, method.toUpperCase())){ // throw new IllegalArgumentException("請求方式設置錯誤,不能設置爲:" + method); // } this.method = method.toUpperCase(); return this; } /** * 設置請求地址,可帶path參數 * 如:/user/{id} */ public HttpClient url(String url) { this.url = url; return this; } /** * 設置請求地址參數,替換url上的參數 * 如:/user/{id} 上的{id} */ public HttpClient pathParams(Map<String, String> pathParams) { this.pathParams.putAll(pathParams); return this; } /** * 添加請求地址參數,替換url上的參數 * 如:/user/{id} 上的{id} */ public HttpClient addPathParam(String key, String value) { this.pathParams.put(key, value); return this; } /** * 設置url請求參數,url問號後面的參數 */ public HttpClient queryParams(Map<String, String> queryParams) { this.queryParams.putAll(queryParams); return this; } /** * 添加url請求參數,url問號後面的參數 */ public HttpClient addQueryParam(String key, String value) { this.queryParams.put(key, value); return this; } /** * 設置表單參數,與body參數衝突,只能設置其中一個,優先使用body */ public HttpClient postParams(Map<String, String> postParams) { this.postParams.putAll(postParams); return this; } /** * 添加表單參數 */ public HttpClient addPostParam(String key, String value) { this.postParams.put(key, value); return this; } /** * 設置請求體body,與post參數衝突,只能設置其中一個 */ public HttpClient body(Object body) { this.body = body; return this; } /** * 獲取最終的請求地址 * * @return */ public String getRequestUrl() { return transformUrl(this.url, pathParams, queryParams); } /** * 發起請求 * * @return * @throws IOException */ public HttpResponse request() throws IOException { response = RestfulHttpClient.request(this); return response; } /** * 添加請求鏈接初始化器 * * @param initializer */ public HttpClient addInitializer(URLConnectionInitializer initializer) { if (initializer == null) { throw new NullPointerException("不能添加空的鏈接初始化器"); } if (initializers == null) { initializers = new ArrayList<>(); } initializers.add(initializer); return this; } public Map<String, String> getHeaders() { return headers; } public int getReadTimeout() { return readTimeout; } public int getConnectTimeout() { return connectTimeout; } public String getMethod() { return method; } public String getUrl() { return url; } public Map<String, String> getQueryParams() { return queryParams; } public Map<String, String> getPathParams() { return pathParams; } public Map<String, String> getPostParams() { return postParams; } public <T> T getBody() { return (T) body; } public HttpResponse getResponse() { return response; } } /** * 請求響應結果 */ public static class HttpResponse { private int code; private Map<String, List<String>> headers; private String requestUrl; private String content; public HttpResponse(int code, Map<String, List<String>> headers, String requestUrl, String content) { this.code = code; this.headers = headers; this.requestUrl = requestUrl; this.content = content; } public <T> T getContent(Class<T> clz) throws IOException { if (StringUtils.isNotBlank(content)) { return new ObjectMapper().readValue(content, clz); } return null; } /** * 獲取響應狀態碼 */ public int getCode() { return code; } /** * 獲取響應頭 */ public Map<String, List<String>> getHeaders() { return headers; } /** * 獲取最後請求地址 */ public String getRequestUrl() { return requestUrl; } /** * 獲取響應內容 */ public String getContent() { return content; } } /** * 發起請求 * * @throws IOException */ private static HttpResponse request(HttpClient client) throws IOException { HttpURLConnection con = instance(client); if (METHOD_GET.equalsIgnoreCase(client.getMethod())) { //GET請求,不用發請求體 return readResponse(con); } String requestBody = null; if (isPrimitiveOrWrapClzOrStr(client.getBody())) { requestBody = client.getBody().toString(); } else if (client.getBody() != null) { requestBody = new ObjectMapper().writeValueAsString(client.getBody()); if (!client.getHeaders().containsKey("Content-Type")) { //設置請求媒體類型爲json提交 con.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); } } else if (client.getPostParams() != null && !client.getPostParams().isEmpty()) { requestBody = toUrlParams(client.getPostParams()); } con.setDoOutput(true); con.setDoInput(true); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(con.getOutputStream(), charset)); if (requestBody != null) { //寫入請求內容 bw.write(requestBody); } bw.close(); return readResponse(con); } /** * 判斷是不是字符串或基本類型或包裝類型 * * @param o * @return */ private static boolean isPrimitiveOrWrapClzOrStr(Object o) { if (o == null) { return false; } else if (o instanceof String) { //是字符串類型 return true; } else if (o.getClass().isPrimitive()) { //是基本類型 return true; } else { try { //是包裝類型 return ((Class) o.getClass().getField("TYPE").get(null)).isPrimitive(); } catch (Exception e) { return false; } } } /** * 讀取響應結果 * * @param con * @return * @throws IOException */ private static HttpResponse readResponse(HttpURLConnection con) throws IOException { try { BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), charset)); StringBuilder sb = new StringBuilder(); String read = null; while ((read = br.readLine()) != null) { sb.append(read); sb.append("\n"); } br.close(); return new HttpResponse(con.getResponseCode(), con.getHeaderFields(), con.getURL().toString(), sb.toString()); } finally { con.disconnect(); } } /** * 初始化請求鏈接 * * @param client * @return * @throws IOException */ private static HttpURLConnection instance(HttpClient client) throws IOException { URL u = new URL(client.getRequestUrl()); HttpURLConnection con = (HttpURLConnection) u.openConnection(); con.setReadTimeout(client.getReadTimeout()); con.setConnectTimeout(client.getConnectTimeout()); con.setRequestMethod(client.getMethod()); Map<String, String> headers = client.getHeaders(); if (headers != null && !headers.isEmpty()) { for (String key : headers.keySet()) { con.setRequestProperty(key, headers.get(key)); } } List<URLConnectionInitializer> initializers = client.initializers; if (initializers != null && !initializers.isEmpty()) { for (URLConnectionInitializer initializer : initializers) { HttpURLConnection init = initializer.init(con, client); if (init != null) { con = init; } } } return con; } /** * 處理url的參數 * 如:/user/{id},將id轉成值 * * @param url * @param pathParams 地址參數 * @param queryParams 請求參數 * @return */ private static String transformUrl(String url, Map<String, String> pathParams, Map<String, String> queryParams) { if (pathParams != null && !pathParams.isEmpty()) { for (String key : pathParams.keySet()) { url = url.replaceAll("\\{" + key + "\\}", pathParams.get(key)); } } if (queryParams != null && !queryParams.isEmpty()) { if (url.indexOf("?") > 0) { url += "&" + toUrlParams(queryParams); } else { url += "?" + toUrlParams(queryParams); } } return url; } /** * 將map參數轉成url參數形式:name1=value2&name2=value2... * * @param paras * @return */ public static String toUrlParams(Map<String, String> paras) { if (paras != null && !paras.isEmpty()) { StringBuffer urlParams = new StringBuffer(); for (String k : paras.keySet()) { urlParams.append(k + "=" + paras.get(k) + "&"); } if (urlParams.length() > 0) { return urlParams.substring(0, urlParams.length() - 1); } } return null; } /** * 獲取全局默認請求headers設置 * * @return */ public static Map<String, String> getDefaultHeaders() { return defaultHeaders; } /** * 設置默認全局默認請求headers * * @param headers * @return */ public static Map<String, String> setDefaultHeaders(Map<String, String> headers) { defaultHeaders.clear(); defaultHeaders.putAll(headers); return getDefaultHeaders(); } /** * 鏈接初始化器 */ public interface URLConnectionInitializer { /** * 初始化http請求鏈接對象 * * @param connection * @return */ HttpURLConnection init(HttpURLConnection connection, HttpClient client); } public static void main(String[] args) throws IOException { String url = "http://localhost:8081/user/{id}"; RestfulHttpClient.HttpResponse response = getClient(url) .post() //設置post請求 .addHeader("token", "tokenValue") //添加header .addPathParam("id", "2") //設置url路徑參數 .addQueryParam("test", "value") //設置url請求參數 .request(); //發起請求 System.out.println(response.getCode()); //響應狀態碼 System.out.println(response.getRequestUrl());//最終發起請求的地址 if (response.getCode() == 200) { //請求成功 System.out.println(response.getContent()); //響應內容 } } }
<a name='TrustAllHttpsInitializer.java'></a> TrustAllHttpsInitializer.javajava
package pres.lnk.utils; import javax.net.ssl.*; import java.io.IOException; import java.net.HttpURLConnection; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; /** * 信任全部https的請求 * 注意:使用該初始器化以後會存在安全認證風險,慎用 * @Author lnk * @Date 2018/5/29 */ public class TrustAllHttpsInitializer implements RestfulHttpClient.URLConnectionInitializer { @Override public HttpURLConnection init(HttpURLConnection connection, RestfulHttpClient.HttpClient client) { String protocol = connection.getURL().getProtocol(); if ("https".equalsIgnoreCase(protocol)) { HttpsURLConnection https = (HttpsURLConnection) connection; trustAllHosts(https); https.setHostnameVerifier(DO_NOT_VERIFY); return https; } return connection; } /** * 覆蓋java默認的證書驗證 */ private static final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }}; /** * 設置不驗證主機 */ private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; /** * 信任全部 * @param connection * @return */ private static SSLSocketFactory trustAllHosts(HttpsURLConnection connection) { SSLSocketFactory oldFactory = connection.getSSLSocketFactory(); try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, null); SSLSocketFactory newFactory = sc.getSocketFactory(); connection.setSSLSocketFactory(newFactory); } catch (Exception e) { e.printStackTrace(); } return oldFactory; } public static void main(String[] args) throws IOException { String url = "https://b2b.10086.cn/b2b/main/viewNoticeContent.html?noticeBean.id="; RestfulHttpClient.HttpResponse response = RestfulHttpClient.getClient(url) .addInitializer(new TrustAllHttpsInitializer()) .request(); //發起請求 System.out.println(response.getCode()); //響應狀態碼 System.out.println(response.getRequestUrl());//最終發起請求的地址 if(response.getCode() == 200){ //請求成功 System.out.println(response.getContent()); //響應內容 } } }