Restful Api調用工具類

<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;

/**
 * &lt;p&gt;RestfulApi請求工具&lt;/p&gt;
 * &lt;a href="http://blog.csdn.net/lnktoking/article/details/79174187"&gt;使用說明&lt;/a&gt;
 *
 * @author lnk
 */
public class RestfulHttpClient {
    /**
     * 全局默認請求頭
     */
    private static final Map&lt;String, String&gt; defaultHeaders = new HashMap&lt;&gt;();
    /**
     * 全局鏈接初始化器
     */
    private static List&lt;URLConnectionInitializer&gt; 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&lt;String, String&gt; 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&lt;&gt;();
        }
        initializers.add(initializer);
    }

    /**
     * 請求客戶端
     */
    public static class HttpClient {
        private Map&lt;String, String&gt; headers;
        private int readTimeout = RestfulHttpClient.readTimeout;
        private int connectTimeout = RestfulHttpClient.connectTimeout;
        private String method = METHOD_GET;
        private String url;
        private Map&lt;String, String&gt; pathParams;
        private Map&lt;String, String&gt; queryParams;
        private Map&lt;String, String&gt; postParams;
        private Object body;
        private HttpResponse response;
        private List&lt;URLConnectionInitializer&gt; initializers;

        public HttpClient(String url) {
            if (StringUtils.isBlank(url)) {
                throw new IllegalArgumentException("請求地址不能爲空");
            }
            this.url = url;
            headers = new HashMap&lt;&gt;();
            pathParams = new HashMap&lt;&gt;();
            queryParams = new HashMap&lt;&gt;();
            postParams = new HashMap&lt;&gt;();
            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&lt;String, String&gt; 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&lt;String, String&gt; 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&lt;String, String&gt; 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&lt;String, String&gt; 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&lt;String, String&gt; 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&lt;&gt;();
            }
            initializers.add(initializer);
            return this;
        }

        public Map&lt;String, String&gt; 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&lt;String, String&gt; getQueryParams() {
            return queryParams;
        }

        public Map&lt;String, String&gt; getPathParams() {
            return pathParams;
        }

        public Map&lt;String, String&gt; getPostParams() {
            return postParams;
        }

        public &lt;T&gt; T getBody() {
            return (T) body;
        }

        public HttpResponse getResponse() {
            return response;
        }
    }

    /**
     * 請求響應結果
     */
    public static class HttpResponse {
        private int code;
        private Map&lt;String, List&lt;String&gt;&gt; headers;
        private String requestUrl;
        private String content;

        public HttpResponse(int code, Map&lt;String, List&lt;String&gt;&gt; headers, String requestUrl, String content) {
            this.code = code;
            this.headers = headers;
            this.requestUrl = requestUrl;
            this.content = content;
        }

        public &lt;T&gt; T getContent(Class&lt;T&gt; clz) throws IOException {
            if (StringUtils.isNotBlank(content)) {
                return new ObjectMapper().readValue(content, clz);
            }
            return null;
        }

        /**
         * 獲取響應狀態碼
         */
        public int getCode() {
            return code;
        }

        /**
         * 獲取響應頭
         */
        public Map&lt;String, List&lt;String&gt;&gt; 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 &amp;&amp; !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&lt;String, String&gt; headers = client.getHeaders();
        if (headers != null &amp;&amp; !headers.isEmpty()) {
            for (String key : headers.keySet()) {
                con.setRequestProperty(key, headers.get(key));
            }
        }

        List&lt;URLConnectionInitializer&gt; initializers = client.initializers;
        if (initializers != null &amp;&amp; !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&lt;String, String&gt; pathParams, Map&lt;String, String&gt; queryParams) {
        if (pathParams != null &amp;&amp; !pathParams.isEmpty()) {
            for (String key : pathParams.keySet()) {
                url = url.replaceAll("\\{" + key + "\\}", pathParams.get(key));
            }
        }
        if (queryParams != null &amp;&amp; !queryParams.isEmpty()) {
            if (url.indexOf("?") &gt; 0) {
                url += "&amp;" + toUrlParams(queryParams);
            } else {
                url += "?" + toUrlParams(queryParams);
            }
        }
        return url;
    }

    /**
     * 將map參數轉成url參數形式:name1=value2&amp;name2=value2...
     *
     * @param paras
     * @return
     */
    public static String toUrlParams(Map&lt;String, String&gt; paras) {
        if (paras != null &amp;&amp; !paras.isEmpty()) {
            StringBuffer urlParams = new StringBuffer();
            for (String k : paras.keySet()) {
                urlParams.append(k + "=" + paras.get(k) + "&amp;");
            }
            if (urlParams.length() &gt; 0) {
                return urlParams.substring(0, urlParams.length() - 1);
            }
        }
        return null;
    }

    /**
     * 獲取全局默認請求headers設置
     *
     * @return
     */
    public static Map&lt;String, String&gt; getDefaultHeaders() {
        return defaultHeaders;
    }

    /**
     * 設置默認全局默認請求headers
     *
     * @param headers
     * @return
     */
    public static Map&lt;String, String&gt; setDefaultHeaders(Map&lt;String, String&gt; 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());  //響應內容
        }
    }
}
相關文章
相關標籤/搜索