JAVA造輪子之-HTTP工具類

Java經常使用HTTP工具類,支持get,post,put,delete幾種method方式,可自定義參數,自定義header,請求內容等;html

新增對HTTPS的支技;java

HttpUtils.javaspring

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

/**
 * @author JL
 * @version V1.0
 * @Description 用java.net.HttpURLConnection進行http操做工具類
 */
public class HttpUtils {

    static final int CONNECT_TIMEOUT_MILLES = 3000;
    static final Charset ENCODING;
    public static final String HTTP_GET = "GET";
    public static final String HTTP_PUT = "PUT";
    public static final String HTTP_POST = "POST";
    public static final String HTTP_DELETE = "DELETE";
    static final String [] METHODS;

    static {
        ENCODING = Charset.forName("UTF-8");
        METHODS = new String[]{HTTP_GET, HTTP_PUT, HTTP_POST, HTTP_DELETE};
    }

    public static String doGet(String url, Map<String, String> headers, Map<String,String> params, String content) throws IOException {
        return doOutput(url, HTTP_GET, headers, params, content);
    }

    public static String doPost(String url, Map<String, String> headers, Map<String,String> params, String content) throws IOException {
        return doOutput(url, HTTP_POST, headers, params, content);
    }

    public static String doSslGet(String url, Map<String, String> headers, Map<String,String> params, String content) throws IOException {
        return doOutput(url, HTTP_GET, headers, params, content, true);
    }

    public static String doSslPost(String url, Map<String, String> headers, Map<String,String> params, String content) throws IOException {
        return doOutput(url, HTTP_POST, headers, params, content, true);
    }

    public static String doJsonPost(String url, Map<String, String> headers, Map<String,String> params, String content) throws IOException {
        params = (params != null) ? params : new HashMap<>();
        params.put("Content-Type", "application/Json; charset=UTF-8");
        return doOutput(url, HTTP_POST, headers, params, content);
    }


    public static String doPut(String url, Map<String, String> headers, Map<String,String> params, String content) throws IOException {
        return doOutput(url, HTTP_PUT, headers, params, content);
    }

    public static String doDelete(String url, Map<String, String> headers, Map<String,String> params, String content) throws IOException {
        return doOutput(url, HTTP_DELETE, headers, params, content);
    }

    public static String doOutput(final String url,final  String method,final Map<String, String> headers,final  Map<String,String> params,final String content) throws IOException {
        return doOutput(url, method, headers, params, content,false);

    }

    public static String doOutput(final String url,final String method,final Map<String, String> headers,final Map<String,String> params,final String content,boolean isSsl) throws IOException {
        HttpURLConnection conn = null;
        try{
            conn = createConnection(setParams(url, params), isSsl);
            setMethod(conn, method);
            setHeaders(conn, headers);
            conn.connect();
            output(conn, content);
            return input(conn);
        }catch(IOException ioe){
            ioe.printStackTrace();
            throw ioe;
        } finally{
            connClose(conn);
        }
    }

    private static void connClose(HttpURLConnection conn){
        if (conn != null){
            conn.disconnect();
        }
    }

    private static String input(HttpURLConnection conn) throws IOException{
        int len ;
        char[] cbuf = new char[1024 * 8];
        StringBuilder buf = new StringBuilder();
        int status = conn.getResponseCode();
        InputStream in = null;
        BufferedReader reader = null;
        try{
            in = conn.getErrorStream();
            if (in == null && status < 400) { //400或以上表示:訪問的頁面域名不存在或者請求錯誤、服務端異常
                in = conn.getInputStream();
            }
            if (in != null){
                reader = new BufferedReader(new InputStreamReader(in, ENCODING));
                while ((len = reader.read(cbuf)) > 0){
                    buf.append(cbuf, 0 , len);
                }
            }
        }finally{
            if (reader != null){
                reader.close();
            }
            if (in != null){
                in.close();
            }
        }
        return buf.toString();
    }

    private static void output(HttpURLConnection conn, String content) throws IOException {
        if (StringUtils.isBlank(content))
            return ;
        OutputStream out = conn.getOutputStream();
        try{
            out.write(content.getBytes(ENCODING));
        } finally{
            if (out != null){
                out.flush();
                out.close();
            }
        }
    }

    private static HttpURLConnection createConnection(String url, boolean isSsl) throws IOException {
        if (isSsl) {
            try {
                httpssl();//ssl協議
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        HttpURLConnection conn = (HttpURLConnection)(new URL(url)).openConnection();
        setConfig(conn);
        return conn;
    }

    private static void setMethod(HttpURLConnection conn, String method) throws IOException{
        Assert.isTrue(StringUtils.containsAny(method,METHODS),"只支持GET、POST、PUT、DELETE操做");
        conn.setRequestMethod(method);
    }

    private static void setConfig(HttpURLConnection conn){
        conn.setConnectTimeout(CONNECT_TIMEOUT_MILLES);
        conn.setUseCaches(false);
        conn.setInstanceFollowRedirects(true);
        conn.setRequestProperty("Connection", "close");
        //conn.setRequestProperty("Content-Type", "application/Json; charset=UTF-8");//這個根據需求,自已加,也能夠放到headersc參數內
        conn.setDoOutput(true);//是否啓用輸出流,method=get,請求參數是拼接在地址檔,默認爲false
        conn.setDoInput(true);//是否啓用輸入流
    }

    private static void setHeaders(HttpURLConnection conn, Map<String,String> headers){
        if (headers == null || headers.size() <= 0) return ;
        headers.forEach((k,v) -> conn.setRequestProperty(k,v));//設置自定義header參數
    }

    private static String setParams(String url, Map<String, String> params){
        if (params == null || params.size() <= 0)
            return url;
        StringBuilder sb = new StringBuilder(url);
        sb.append("?");
        params.forEach((k,v)->sb.append(k).append("=").append(v).append("&"));
        return sb.substring(0, sb.length() - 1);
    }

    /**
     * 建立ssl鏈接
     * SSL協議位於TCP/IP協議與各類應用層協議之間,爲數據通信提供安全支持,提供以下支持:
     * 1)認證用戶和服務器,確保數據發送到正確的客戶機和服務器;
     * 2)加密數據以防止數據中途被竊取;
     * 3)維護數據的完整性,確保數據在傳輸過程當中不被改變。
     * @throws Exception
     */
    public static void httpssl() throws Exception {
        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
        javax.net.ssl.TrustManager tm = new SslManager();
        trustAllCerts[0] = tm;
        javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            public boolean verify(String str, SSLSession session) {
                return true;
            }
        });
    }

    //TrustManager是JSSE 信任管理器的基接口,管理和接受提供的證書,經過JSSE能夠很容易地編程實現對HTTPS站點的訪問
    //X509TrustManager此接口的實例管理使用哪個 X509 證書來驗證遠端的安全套接字
    public static class SslManager implements TrustManager, 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 new X509Certificate[0];
        }
    }

    public static void main(String[] args) throws IOException {
//        https://www.baidu.com/s?wd=HttpURLConnection
//        Map<String,String> params = new HashMap<String, String>();
//        params.put("wd","HttpURLConnection");
//        String html = doGet("https://www.baidu.com/s",null, params, null);
//        System.out.println(html);

        //https 測試
        String httpsUrl = "https://ifeve.com/google-guava/";
        String html2 = doSslGet(httpsUrl,null, null, null);
        System.out.println(html2);
    }

}

說明:apache

作過項目的人都知道,不少寫過的可重複利用的代碼塊或有用的工具類沒有怎麼整理,當須要的時候,又得打開項目查找一翻,雖然功能開發不難,可是又得花時間成本去寫去測試,這樣的重複造輪子的事情太屢次了;所以不如把輪子保留,供你們一塊兒使用;編程

1.這個輪子能夠有:須要使用的時候確實還不存在這個組件。
2.我須要的時候輪子不在:每一種技術或工具產生都有它的項目背景,當代碼寫在項目裏的時候,我知道有這個東西,當換了一個項目或公司後,沒有備份也沒有記錄,這個時候你不在了,又得花時間手打一遍;
3.我不知道是否是造輪子:大多數狀況下初學者很難分清楚本身是否是在重複造輪子,事實上造輪子不是我目的。個人目的是完成工做任務,任務完成的速度越快越好,質量越高越好。而不是去判斷本身在不在造輪子。
4.不想重複花時間造輪子:有時候還會碰到一些並不困難可是很佔時間的東西,固然有現成的輪子是花時間最少的;
5.我就是想學習輪子:初學者的並非在重複造輪子,而是學習後以提升爲本身的知識與技能。安全

輪子有過測試,但不免有失誤,若有錯誤處,還敬請指出;服務器

相關文章
相關標籤/搜索