您的位置:首页 > 理论基础 > 计算机网络

关于JAVA发送Https请求(HttpsURLConnection和HttpURLConnection)

2018-02-02 15:03 666 查看
转自:http://blog.csdn.net/shumeng_xiaoyan/article/details/76503601

https协议对于开发者而言其实只是多了一步证书验证的过程。这个证书正常情况下被jdk/jre/security/cacerts所管理。里面证书包含两种情况:

1、机构所颁发的被认证的证书,这种证书的网站在浏览器访问时https头显示为绿色如百度

2、个人所设定的证书,这种证书的网站在浏览器里https头显示为红色×,且需要点击信任该网站才能继续访问。而点击信任这一步的操作就是我们在java代码访问https网站时区别于http请求需要做的事情。

所以JAVA发送Https请求有两种情况,三种解决办法:

第一种情况:Https网站的证书为机构所颁发的被认证的证书,这种情况下和http请求一模一样,无需做任何改变,用HttpsURLConnection或者HttpURLConnection都可以

[java] view
plain copy

public static void main(String[] args) throws Exception{  

        URL serverUrl = new URL("https://xxxx");  

        HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection();  

        conn.setRequestMethod("GET");  

        conn.setRequestProperty("Content-type", "application/json");  

        //必须设置false,否则会自动redirect到重定向后的地址  

        conn.setInstanceFollowRedirects(false);  

        conn.connect();  

        String result = getReturn(conn);  

    }  

  

    /*请求url获取返回的内容*/  

    public static String getReturn(HttpURLConnection connection) throws IOException{  

        StringBuffer buffer = new StringBuffer();  

        //将返回的输入流转换成字符串  

        try(InputStream inputStream = connection.getInputStream();  

            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, ConstantInfo.CHARSET);  

            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);){  

            String str = null;  

            while ((str = bufferedReader.readLine()) != null) {  

                buffer.append(str);  

            }  

            String result = buffer.toString();  

            return result;  

        }  

}  

第二种情况:个人所设定的证书,这种证书默认不被信任,需要我们自己选择信任,信任的办法有两种:

A、将证书导入java的运行环境中

从该网站下载或者从网站开发者出获取证书cacert.crt
运行命令将证书导入java运行环境:keytool -import -keystore %JAVA_HOME%\jre\lib\security\cacerts
-file cacert.crt -alias xxx

完成。java代码中发送https的请求和http一样,同第一种情况。

B、忽略证书验证过程,忽略之后任何Https协议网站皆能正常访问,同第一种情况

[java] view
plain copy

import java.security.cert.CertificateException;  

import java.security.cert.X509Certificate;  

import javax.net.ssl.X509TrustManager;  

public class MyX509TrustManager implements X509TrustManager {  

  

    @Override  

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

    }  

  

    @Override  

    public void checkServerTrusted(X509Certificate[] ax509certificate,String s) throws CertificateException {  

    }  

  

    @Override  

    public X509Certificate[] getAcceptedIssuers() {  

        // TODO Auto-generated method stub  

        return null;  

    }  

}  

[java] view
plain copy

public static void main(String[] args) throws Exception{  

        SSLContext sslcontext = SSLContext.getInstance("SSL","SunJSSE");  

        sslcontext.init(null, new TrustManager[]{new MyX509TrustManager()}, new java.security.SecureRandom());  

        URL url = new URL("https://xxxx");  

        HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {  

            public boolean verify(String s, SSLSession sslsession) {  

                System.out.println("WARNING: Hostname is not matched for cert.");  

                return true;  

            }  

        };  

        HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);  

        HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());  

        //之后任何Https协议网站皆能正常访问,同第一种情况  

}  

C、java代码中加载证书,必须使用HttpsURLConnection方式

从网站开发者出获取生成证书的密钥库cacert.keystore

[java] view
plain copy

import java.io.FileInputStream;  

import java.security.KeyStore;  

import java.security.cert.CertificateException;  

import java.security.cert.X509Certificate;  

import javax.net.ssl.TrustManager;  

import javax.net.ssl.TrustManagerFactory;  

import javax.net.ssl.X509TrustManager;  

public class MyX509TrustManager implements X509TrustManager {  

    /* 

     * The default X509TrustManager returned by SunX509.  We'll delegate 

     * decisions to it, and fall back to the logic in this class if the 

     * default X509TrustManager doesn't trust it. 

     */  

    X509TrustManager sunJSSEX509TrustManager;  

    MyX509TrustManager() throws Exception {  

        // create a "default" JSSE X509TrustManager.  

        KeyStore ks = KeyStore.getInstance("JKS");  

        ks.load(new FileInputStream("cancert.keystore"),  

                "changeit".toCharArray());  

        TrustManagerFactory tmf =  

                TrustManagerFactory.getInstance("SunX509", "SunJSSE");  

        tmf.init(ks);  

        TrustManager tms [] = tmf.getTrustManagers();  

            /* 

             * Iterate over the returned trustmanagers, look 

             * for an instance of X509TrustManager.  If found, 

             * use that as our "default" trust manager. 

             */  

        for (int i = 0; i < tms.length; i++) {  

            if (tms[i] instanceof X509TrustManager) {  

                sunJSSEX509TrustManager = (X509TrustManager) tms[i];  

                return;  

            }  

        }  

            /* 

             * Find some other way to initialize, or else we have to fail the 

             * constructor. 

             */  

        throw new Exception("Couldn't initialize");  

    }  

    /* 

     * Delegate to the default trust manager. 

     */  

    public void checkClientTrusted(X509Certificate[] chain, String authType)  

            throws CertificateException {  

        try {  

            sunJSSEX509TrustManager.checkClientTrusted(chain, authType);  

        } catch (CertificateException excep) {  

            // do any special handling here, or rethrow exception.  

        }  

    }  

    /* 

     * Delegate to the default trust manager. 

     */  

    public void checkServerTrusted(X509Certificate[] chain, String authType)  

            throws CertificateException {  

        try {  

            sunJSSEX509TrustManager.checkServerTrusted(chain, authType);  

        } catch (CertificateException excep) {  

                /* 

                 * Possibly pop up a dialog box asking whether to trust the 

                 * cert chain. 

                 */  

        }  

    }  

    /* 

     * Merely pass this through. 

     */  

    public X509Certificate[] getAcceptedIssuers() {  

        return sunJSSEX509TrustManager.getAcceptedIssuers();  

    }  

}  

[java] view
plain copy

  

[java] view
plain copy

public static void main(String[] args) throws Exception{  

        SSLContext sslcontext = SSLContext.getInstance("SSL","SunJSSE");  

        sslcontext.init(null, new TrustManager[]{new MyX509TrustManager()}, new java.security.SecureRandom());  

        URL serverUrl = new URL("https://xxxx");  

        HttpsURLConnection conn = (HttpsURLConnection) serverUrl.openConnection();  

        conn.setSSLSocketFactory(sslcontext.getSocketFactory());  

        conn.setRequestMethod("GET");  

        conn.setRequestProperty("Content-type", "application/json");  

        //必须设置false,否则会自动redirect到重定向后的地址  

        conn.setInstanceFollowRedirects(false);  

        conn.connect();  

        String result = getReturn(conn);  

    }  

  

    /*请求url获取返回的内容*/  

    public static String getReturn(HttpsURLConnection connection) throws IOException{  

        StringBuffer buffer = new StringBuffer();  

        //将返回的输入流转换成字符串  

        try(InputStream inputStream = connection.getInputStream();  

            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, ConstantInfo.CHARSET);  

            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);){  

            String str = null;  

            while ((str = bufferedReader.readLine()) != null) {  

                buffer.append(str);  

            }  

            String result = buffer.toString();  

            return result;  

        }  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: