JAVA造轮子之-HTTP工具类

Java常用HTTP工具类,支持get,post,put,delete几种method方式,可自定义参数,自定义header,请求内容等;

新增对HTTPS的支技;

HttpUtils.java

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 headers, Map params, String content) throws IOException {
        return doOutput(url, HTTP_GET, headers, params, content);
    }

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

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

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

    public static String doJsonPost(String url, Map headers, Map 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 headers, Map params, String content) throws IOException {
        return doOutput(url, HTTP_PUT, headers, params, content);
    }

    public static String doDelete(String url, Map headers, Map 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 headers,final  Map 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 headers,final Map 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 headers){
        if (headers == null || headers.size() <= 0) return ;
        headers.forEach((k,v) -> conn.setRequestProperty(k,v));//设置自定义header参数
    }

    private static String setParams(String url, Map 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 params = new HashMap();
//        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);
    }

}

说明:

做过项目的人都知道,很多写过的可重复利用的代码块或有用的工具类没有怎么整理,当需要的时候,又得打开项目查找一翻,虽然功能开发不难,但是又得花时间成本去写去测试,这样的重复造轮子的事情太多次了;因此不如把轮子保留,供大家一起使用;

1.这个轮子可以有:需要使用的时候确实还不存在这个组件。
2.我需要的时候轮子不在:每一种技术或工具产生都有它的项目背景,当代码写在项目里的时候,我知道有这个东西,当换了一个项目或公司后,没有备份也没有记录,这个时候你不在了,又得花时间手打一遍;
3.我不知道是不是造轮子:大多数情况下初学者很难分清楚自己是不是在重复造轮子,事实上造轮子不是我目的。我的目的是完成工作任务,任务完成的速度越快越好,质量越高越好。而不是去判断自己在不在造轮子。
4.不想重复花时间造轮子:有时候还会碰到一些并不困难但是很占时间的东西,当然有现成的轮子是花时间最少的;
5.我就是想学习轮子:初学者的并不是在重复造轮子,而是学习后以提高为自己的知识与技能。

轮子有过测试,但难免有失误,如有错误处,还敬请指出;

转载于:https://my.oschina.net/u/437309/blog/3066656

你可能感兴趣的:(JAVA造轮子之-HTTP工具类)