发表于: 2017-06-27 23:34:19

1 1088


一、今天完成的事情

   和智勇讨论了一下职位列表是否使用三连表查询,为了一下培哥告诉我是可以的,然后就使用三连等O.O_尴尬而又失礼……

    对于article管理的排序我和智勇想了不同的方法,准备明天评审一起提出来问问

    学习了https实现简单的方法:

 HTTPS的认证分为单向认证和双向认证!

但是,在实际应用中,我们内部系统之间可能也会通过HTTPS协议进行调用,但是内部系统进行调用的时候,可能不需要进行SSL验证,所以需要绕过SSL验证,实现HTTPS访问。



public class HttpsWithoutSSLTest implements X509TrustManager {

    private static Logger logger = LoggerFactory.getLogger(HttpsWithoutSSLTest.class);


    /**

     * 不带SSL验证的HTTPS

     * @param url

     * @param reportContent  需要传输的内容

     * @param charset  字符编码

     * @return

     */

    public static String sendHttps(String url,String reportContent,String charset){

        if(StringUtils.isBlank(reportContent))

            reportContent = "";


        URL r_url = null;

        /**

         * HttpsURLConnection 继承 HttpURLConnection,虽然只有一个字母的差别,但是相比较与HttpURLConnection更安全些

         */


        HttpsURLConnection urlConn = null;

        OutputStream out = null;

        try {

            /**

             * SSLContext 表示着安全套接字协议的一个实现,它充当安全套接字工厂或者SSLEngine工厂。

             * 什么是安全套接字呢?其实就是SSLSocket。它是一种比较安全的socket.你可以理解为在底层网络传输协议(如TCP)上添加了安全保护层。

             * 什么SSLEngine?其实就是一种SSL的引擎类

             * 通过SSLContext可以获得SSLSocket和SSLEngine

             */

            SSLContext sc = SSLContext.getInstance("SSL");

            /**

             * init(KeyManager[] keyManagers,TrustManager[] trustManager,SecureRandom random)用于初始化上下文。

             *KeyManager 是一个接口,用于管理密钥

             * TrustManager  是用于管理信任证书的一个接口

             * SecureRandom 是一个加密的随机数生成器

             *

             * 注意:因为我们要实现不带SSL验证的HTTPS,所以在初始化SSLContext的时候,第一个参数密钥管理器设为null

             * 第二个参数是信任管理器。如果说我们要实现带有SSL认证的HTTPS,这个参数就是对方证书的管理器,也是验证的关键所在,需要去验证对方的证书。

             * 但我们需要绕过证书实现HTTPS,所以我们需要自己重写TrustManager,在这里实现了X509TrustManager接口

             */

            sc.init(null, new TrustManager[] { new HttpsWithoutSSLTest() },new SecureRandom());

            /**

             * HostnameVerifier  是用于主机名验证的基接口,我们知道实现SSL,需要进行多次握手。在握手期间,如果URL的主机名和服务器的标识主机名不匹配,则验证机制则会回调这个接口的实现程序来确定是否允许此链接。

             * 接口方法为verify(String urlHostName, SSLSession session),以下代码返回true,意味着默认URL主机名和服务器的标识主机名匹配!

             */

            HostnameVerifier hv = new HostnameVerifier() {

                public boolean verify(String urlHostName, SSLSession session) {

                    return true;

                }

            };

            r_url = new URL(url);

            /**

             * 获取HttpsURLConnection

             */

            urlConn = (HttpsURLConnection) r_url.openConnection();

            /**

             * 设置此链接创建安全套接字的时候使用的SSLSocketFactory

             */

            urlConn.setSSLSocketFactory(sc.getSocketFactory());

            urlConn.setHostnameVerifier(hv);

            urlConn.setDoOutput(true);

            urlConn.setDoInput(true);

            urlConn.setConnectTimeout(5000);

            urlConn.setReadTimeout(6000);

            urlConn.setRequestProperty("Charset", charset);

            urlConn.setRequestMethod("POST");

            out = urlConn.getOutputStream();

            out.write(reportContent.getBytes(charset));

            out.flush();

        } catch (Exception e) {

            logger.error("发送Https请求异常" , e);

            throw new RuntimeException(e.getMessage());

        }finally {

            try {

                if(out != null)

                    out.close();

            } catch (Exception e) {

                logger.error("关闭https网络流写流关闭失败",e);

            }

        }


        /**

         * 通过IO流进行返回报文的读取

         */

        StringBuffer buffer = new StringBuffer();

        InputStream input = null;

        try {

            if(urlConn != null){

                input = urlConn.getInputStream();

                byte[] bt = new byte[1024];

                int length = -1;

                while ((length = input.read(bt)) != -1) {

                    buffer.append(new String(bt, 0, length, charset));

                }

            }

        } catch (Exception e) {

            logger.error("接收Https响应数据异常" , e);

            throw new RuntimeException(e.getMessage());

        }finally{

            if(input != null){

                try {

                    input.close();

                } catch (IOException e) {

                    logger.error("Https数据接收完毕后,关闭流异常" + e);

                }

            }

        }

        String data = buffer.toString();

        logger.info("Https 响应内容:"+data);


        return data;

    }

    @Override

    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        //To change body of implemented methods use File | Settings | File Templates.

    }


    @Override

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

        //To change body of implemented methods use File | Settings | File Templates.

    }


    @Override

    public X509Certificate[] getAcceptedIssuers() {

        return null;  //To change body of implemented methods use File | Settings | File Templates.

    }

}



客户端的方法没有理论更上,这里代码详细注释了服务端的方法

二、遇到的问题:无

三、明天计划的事情

四、收获、还是蛮多的,今天听了一下对动态查询的使用~对于怎么使用更加清晰了,公司里好像测的时候不是用fastjson,等我再研究一下po m。


返回列表 返回列表
评论

    分享到