Android-工作遭遇-URLConnection原生请求http和https忽略证书

Android网络请求框架非常多,github一搜就是一堆.我的博客就不讲这些,我就讲讲原生已经够用了.

HttpURLConnection是Android提供的一个网络请求库,个人认为,还是蛮好用的.

HttpsURLConnection是本身就继承自HttpURLConnection的类

首先是忽略证书这一块.有些请求涉及到请求证书.加载证书似乎很麻烦.(不麻烦,我不想加载)

首先需要初始化,一般我喜欢封装一个工具类,然后在静态代码块中,进行初始化

 static {
        try {
            ctx = SSLContext.getInstance("TLS");
            ctx.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager(null)}, new SecureRandom());
            ctx.getClientSessionContext().setSessionTimeout(15);
            ctx.getClientSessionContext().setSessionCacheSize(1000);
            socketFactory = ctx.getSocketFactory();
        } catch (Exception ignored) {

        }

        verifier = new HostnameVerifier();
    }
其中的new TrustManager[]{new WebUtils.DefaultTrustManager(null)}.只是继承了X509TrustManager进行使用
    private static class DefaultTrustManager implements X509TrustManager {
        private DefaultTrustManager(Object o) {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
    }
HostnameVerifier中我对忽略规则做了处理,特殊请求的url,证书还是需要的
Pattern.compile("([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)");

如果匹配上这条正则.则需要ssl协议

关键点在于获取Connection的时候做的处理

// new URL即可,请求方法,post还是get.Content-type,一般都是utf-8
 private static HttpURLConnection getConnection(URL url, String method, String ctype) throws IOException {
        HttpURLConnection conn = null;
        if ("https".equals(url.getProtocol())) {
// ssl证书管理在这里
            HttpsURLConnection connHttps = (HttpsURLConnection) url.openConnection();
            connHttps.setSSLSocketFactory(socketFactory);
            connHttps.setHostnameVerifier(verifier);
            conn = connHttps;
        } else {
            conn = (HttpURLConnection) url.openConnection();
        }
        conn.setRequestMethod(method);
        conn.setAllowUserInteraction(true);
        conn.setInstanceFollowRedirects(true);
        if (method.equalsIgnoreCase("post")) {
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
        }
        // cookie也可以在这里设置
//        conn.setRequestProperty("Set-Cookie", "");
        conn.setRequestProperty("User-Agent","");
        conn.setRequestProperty("Content-Type", "");

        return conn;
    }

使用也是非常的简单


    public static byte[] doGet(String url, Map<String, String> params) {
        HttpURLConnection conn         = null;
        String            responseBody = null;
        byte[]            bytes        = new byte[0];
        try {
//   这里我写了一个方法.把get请求的参数作为拼接
            conn = getConnection(new URL(getQueryUrl(url, params)), "GET", "*/*;charset=utf-8");
            conn.setReadTimeout(0);
            conn.setConnectTimeout(0);
            bytes = readInputStream(conn.getInputStream());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        return bytes;
    }

附上完整工具类

public class WebUtils {
    private static final String           DEFAULT_CHARSET = "UTF-8";
    private static final String           METHOD_POST     = "POST";
    private static final String           METHOD_GET      = "GET";
    private static       SSLContext       ctx             = null;
    private static       HostnameVerifier verifier        = null;
    private static       SSLSocketFactory socketFactory   = null;

    private WebUtils() {
    }

    public static String doPostStringResponse(String url, String json) {
        Log.d("WebUtils", url);
        HttpURLConnection conn         = null;
        String            responseBody = null;
        try {
            conn = getConnection(new URL(url), "POST", "application/json;charset=utf-8");
            conn.setReadTimeout(0);
            conn.setConnectTimeout(0);
// post发送json数据
            if (!TextUtils.isEmpty(json)) {
                byte[] bytes = json.getBytes();
                conn.setRequestProperty("Content-Length", bytes.length + "");
                OutputStream outputStream = conn.getOutputStream();
                outputStream.write(bytes);
                outputStream.flush();
                outputStream.close();
            }
            byte[] bytes = readInputStream(conn.getInputStream());
            responseBody = new String(bytes, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        return responseBody;
    }


    public static byte[] doGet(String url) {
        return doGet(url, null);
    }


    public static byte[] doGet(String url, Map<String, String> params) {
        HttpURLConnection conn         = null;
        String            responseBody = null;
        byte[]            bytes        = new byte[0];
        try {
            conn = getConnection(new URL(getQueryUrl(url, params)), "GET", "*/*;charset=utf-8");
            conn.setReadTimeout(0);
            conn.setConnectTimeout(0);
            bytes = readInputStream(conn.getInputStream());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        return bytes;
    }

 
    private static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[]                buffer = new byte[1024];
        int                   len    = 0;
        ByteArrayOutputStream bos    = new ByteArrayOutputStream();

        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        inputStream.close();
        return bos.toByteArray();
    }

    private static HttpURLConnection getConnection(URL url, String method, String ctype) throws IOException {
        HttpURLConnection conn = null;
        if ("https".equals(url.getProtocol())) {
            HttpsURLConnection connHttps = (HttpsURLConnection) url.openConnection();
            connHttps.setSSLSocketFactory(socketFactory);
            connHttps.setHostnameVerifier(verifier);
            conn = connHttps;
        } else {
            conn = (HttpURLConnection) url.openConnection();
        }
        conn.setRequestMethod(method);
        conn.setAllowUserInteraction(true);
        conn.setInstanceFollowRedirects(true);
// post方法必须加上,get方法是不需要这些,否则会失败
        if (method.equalsIgnoreCase("post")) {
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
        }
        // cookie也可以在这里设置
//        conn.setRequestProperty("Set-Cookie", "");
        conn.setRequestProperty("User-Agent", Settings.UA);
        conn.setRequestProperty("Content-Type", ctype);

        return conn;
    }

    static {
        try {
            ctx = SSLContext.getInstance("TLS");
            ctx.init(new KeyManager[0], new TrustManager[]{new WebUtils.DefaultTrustManager(null)}, new SecureRandom());
            ctx.getClientSessionContext().setSessionTimeout(15);
            ctx.getClientSessionContext().setSessionCacheSize(1000);
            socketFactory = ctx.getSocketFactory();
        } catch (Exception ignored) {

        }

        verifier = new HostnameVerifier();
    }

    /**
     * 拼接get数据
     *
     * @param url    地址 
     * @param params get参数
     * @return
     */
    private static String getQueryUrl(String url, Map<String, String> params) {
        StringBuilder neoUrl = new StringBuilder(url);
        if (params != null) {
            neoUrl.append("?");
            for (Map.Entry<String, String> stringStringEntry : params.entrySet()) {
                neoUrl.append(stringStringEntry.getKey()).append("=").append(stringStringEntry.getValue()).append("&");
            }
            neoUrl = new StringBuilder(neoUrl.substring(0, neoUrl.length() - 1));
        }
        return neoUrl.toString();
    }


    private static class DefaultTrustManager implements X509TrustManager {
        private DefaultTrustManager(Object o) {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
    }

   

}

以及HostnameVerifier

public class HostnameVerifier implements javax.net.ssl.HostnameVerifier {
    public static final  HostnameVerifier INSTANCE             = new HostnameVerifier();
    private static final int              ALT_DNS_NAME         = 2;
    private static final int              ALT_IPA_NAME         = 7;
    private static final Pattern          VERIFY_AS_IP_ADDRESS = Pattern.compile("([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)");

    HostnameVerifier() {
    }

    public boolean verify(String host, SSLSession session) {
        try {
            Certificate[] certificates = session.getPeerCertificates();
            return this.verify(host, (X509Certificate)certificates[0]);
        } catch (SSLException var4) {
            return false;
        }
    }

    public boolean verify(String host, X509Certificate certificate) {
        return verifyAsIpAddress(host)?this.verifyIpAddress(host, certificate):this.verifyHostname(host, certificate);
    }

    private boolean verifyIpAddress(String ipAddress, X509Certificate certificate) {
        List<String> altNames = getSubjectAltNames(certificate, 7);
        int          i        = 0;

        for(int size = altNames.size(); i < size; ++i) {
            if(ipAddress.equalsIgnoreCase((String)altNames.get(i))) {
                return true;
            }
        }

        return false;
    }

    private boolean verifyHostname(String hostname, X509Certificate certificate) {
        hostname = hostname.toLowerCase(Locale.US);
        List<String> altNames = getSubjectAltNames(certificate, 2);
        Iterator     var4     = altNames.iterator();

        String altName;
        do {
            if(!var4.hasNext()) {
                return false;
            }

            altName = (String)var4.next();
        } while(!this.verifyHostname(hostname, altName));

        return true;
    }

    public static List<String> allSubjectAltNames(X509Certificate certificate) {
        List<String> altIpaNames = getSubjectAltNames(certificate, 7);
        List<String> altDnsNames = getSubjectAltNames(certificate, 2);
        List<String> result = new ArrayList(altIpaNames.size() + altDnsNames.size());
        result.addAll(altIpaNames);
        result.addAll(altDnsNames);
        return result;
    }

    private static List<String> getSubjectAltNames(X509Certificate certificate, int type) {
        ArrayList result = new ArrayList();

        try {
            Collection<?> subjectAltNames = certificate.getSubjectAlternativeNames();
            if(subjectAltNames == null) {
                return Collections.emptyList();
            } else {
                Iterator var4 = subjectAltNames.iterator();

                while(var4.hasNext()) {
                    Object subjectAltName = var4.next();
                    List<?> entry = (List)subjectAltName;
                    if(entry != null && entry.size() >= 2) {
                        Integer altNameType = (Integer)entry.get(0);
                        if(altNameType != null && altNameType.intValue() == type) {
                            String altName = (String)entry.get(1);
                            if(altName != null) {
                                result.add(altName);
                            }
                        }
                    }
                }

                return result;
            }
        } catch (CertificateParsingException var9) {
            return Collections.emptyList();
        }
    }

    public boolean verifyHostname(String hostname, String pattern) {
        if(hostname != null && hostname.length() != 0 && !hostname.startsWith(".") && !hostname.endsWith("..")) {
            if(pattern != null && pattern.length() != 0 && !pattern.startsWith(".") && !pattern.endsWith("..")) {
                if(!hostname.endsWith(".")) {
                    hostname = hostname + '.';
                }

                if(!pattern.endsWith(".")) {
                    pattern = pattern + '.';
                }

                pattern = pattern.toLowerCase(Locale.US);
                if(!pattern.contains("*")) {
                    return hostname.equals(pattern);
                } else if(pattern.startsWith("*.") && pattern.indexOf(42, 1) == -1) {
                    if(hostname.length() < pattern.length()) {
                        return false;
                    } else if("*.".equals(pattern)) {
                        return false;
                    } else {
                        String suffix = pattern.substring(1);
                        if(!hostname.endsWith(suffix)) {
                            return false;
                        } else {
                            int suffixStartIndexInHostname = hostname.length() - suffix.length();
                            return suffixStartIndexInHostname <= 0 || hostname.lastIndexOf(46, suffixStartIndexInHostname - 1) == -1;
                        }
                    }
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public static boolean verifyAsIpAddress(String host) {
        return VERIFY_AS_IP_ADDRESS.matcher(host).matches();
    }
}

猜你喜欢

转载自blog.csdn.net/ci250454344/article/details/82871965
今日推荐