zoukankan      html  css  js  c++  java
  • commons-httpclient 3.1

    commons-httpclient 3.1 这个包比较老,已经淘汰了。但好多老项目依然在用这个包。

    有一个项目,第三方https,用的自建证书(无耻),导致请求报错:

    使用HttpClient发送Https请求时,出现异常为:
    PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    

      

    百度了一下,发现这篇文章:感谢。
    https://www.cnblogs.com/ll409546297/p/7154542.html

    ---------------------------------------------------------------------

    一、因为在使用https发送请求的时候会涉及,验证方式。但是这种方式在使用的时候很不方便。特别是在请求外部接口的时候,所以这我写了一个跳过验证的方式。(供参考)

    二、加入包,这里用的是commons-httpclient 3.1 的包。一般请求采用最新的httpclient4.5就可以了

    <dependency>
      <groupId>commons-httpclient</groupId>
      <artifactId>commons-httpclient</artifactId>
      <version>3.1</version>
    </dependency>
    

      

    三、这里我们实现3个类

    1、MyX509TrustManager(这个方法直接实现X509TrustManager,X509TrustManager在javax.net.ssl.X509TrustManager里面)

    这里直接实现不用改任何东西

    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import javax.net.ssl.X509TrustManager;
    
    public class MyX509TrustManager implements X509TrustManager {
        /* (non-Javadoc)
        * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String)
        */
        public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
    
        }
        /* (non-Javadoc)
         * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String)
         */
        public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
    
        }
        /* (non-Javadoc)
         * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
         */
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
    

      

    2、MySecureProtocolSocketFactory(这里我们需要用到SSLContext,还需要改写一个实现SecureProtocolSocketFactory的方法)

    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import org.apache.commons.httpclient.ConnectTimeoutException;
    import org.apache.commons.httpclient.HttpClientError;
    import org.apache.commons.httpclient.params.HttpConnectionParams;
    import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
    import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
    
    public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {
    
        //这里添加一个属性,主要目的就是来获取ssl跳过验证
        private SSLContext sslContext = null;
        /**
         * Constructor for MySecureProtocolSocketFactory.
         */
        public MySecureProtocolSocketFactory() {
        }
        /**
         * 这个创建一个获取SSLContext的方法,导入MyX509TrustManager进行初始化
         * @return
         */
        private static SSLContext createEasySSLContext() {
            try {
                SSLContext context = SSLContext.getInstance("SSL");
                context.init(null, new TrustManager[] { new MyX509TrustManager() },
                        null);
                return context;
            } catch (Exception e) {
                throw new HttpClientError(e.toString());
            }
        }
    
        /**
         * 判断获取SSLContext
         * @return
         */
        private SSLContext getSSLContext() {
            if (this.sslContext == null) {
                this.sslContext = createEasySSLContext();
            }
            return this.sslContext;
        }
        //后面的方法基本上就是带入相关参数就可以了
        /*
         * (non-Javadoc)
         *
         * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String,
         *      int, java.net.InetAddress, int)
         */
        public Socket createSocket(String host, int port, InetAddress clientHost,int clientPort) throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(host, port,clientHost, clientPort);
        }
    
        /*
         * (non-Javadoc)
         *
         * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String,
         *      int, java.net.InetAddress, int,
         *      org.apache.commons.httpclient.params.HttpConnectionParams)
         */
        public Socket createSocket(final String host, final int port,final InetAddress localAddress, final int localPort,
                                   final HttpConnectionParams params) throws IOException,UnknownHostException, ConnectTimeoutException {
            if (params == null) {
                throw new IllegalArgumentException("Parameters may not be null");
            }
            int timeout = params.getConnectionTimeout();
            if (timeout == 0) {
                return createSocket(host, port, localAddress, localPort);
            } else {
                return ControllerThreadSocketFactory.createSocket(this, host, port,localAddress, localPort, timeout);
            }
        }
    
        /*
         * (non-Javadoc)
         *
         * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
         */
        public Socket createSocket(String host, int port) throws IOException,UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(host, port);
        }
    
        /*
         * (non-Javadoc)
         *
         * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
         */
        public Socket createSocket(Socket socket, String host, int port,boolean autoClose) throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(socket, host,port, autoClose);
        }
    }
    

      

    3、然后就是httpclient了,这里实现的方式很单间了,只要声明MySecureProtocolSocketFactory加入就可以了Protocol

    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.httpclient.protocol.Protocol;
    import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
    /*
     * 利用HttpClient进行post请求的工具类
     */
    public class HttpClientUtil {
    
        public static String doGet(String url) throws Exception {
            //声明
            ProtocolSocketFactory fcty = new MySecureProtocolSocketFactory();
            //加入相关的https请求方式
            Protocol.registerProtocol("https", new Protocol("https", fcty, 443));
            //发送请求即可
            org.apache.commons.httpclient.HttpClient httpclient = new org.apache.commons.httpclient.HttpClient();
            GetMethod httpget = new GetMethod(url);
            System.out.println("======url:" + url);
            try {
                httpclient.executeMethod(httpget);
                return httpget.getResponseBodyAsString();
            } catch (Exception ex) {
                ex.printStackTrace();
                throw new Exception(ex.getMessage());
            } finally {
                httpget.releaseConnection();
            }
        }
    
    }
    

      

    四、这里基本上就完成了,在会用的时候只要声明MySecureProtocolSocketFactory加入就可以了Protocol,然后就可以实现验证的跳过过了

     

     

     

    使用HttpClient发送Https请求时,出现异常为:PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target————————————————版权声明:本文为CSDN博主「有错误先debug」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_42561919/article/details/100065675

  • 相关阅读:
    SecureCRT远程控制ubuntu
    zedboard启动过程分析
    zedboard之ubuntu环境变量设置
    理解 pkg-config 工具
    linux下 tar解压 gz解压 bz2等各种解压文件使用方法
    zedboard搭建交叉编译环境
    一步一步学ZedBoard & Zynq(四):基于AXI Lite 总线的从设备IP设计
    zedboard 中SDK 修改串口设置(波特率。。。。)
    VC 2010下安装OpenCV2.4.4
    VS2010恢复默认编辑环境的设置
  • 原文地址:https://www.cnblogs.com/achengmu/p/15464843.html
Copyright © 2011-2022 走看看