zoukankan      html  css  js  c++  java
  • Spring RestTemplet https请求

    错误:No subject alternative names matching IP address XXXXXXX found 

    基础知识:

      微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。我们可以使用JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client,最方便、最优雅的Feign, Spring的RestTemplate等。

    RestTemplate简述:
             RestTemplate是Spring提供的用于访问Rest服务(Rest风格、Rest架构)的客户端。
             RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。

    调用RestTemplate的默认构造函数,RestTemplate对象在底层通过使用java.net包下的实现创建HTTP 请求;我们也可以通过使用ClientHttpRequestFactory指定不同的请求方式:

    ClientHttpRequestFactory接口主要提供了两种实现方式:

            1.常用的一种是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层
                的Http请求连接。

             2.常用的另一种方式是使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的
                 Http服务,使用HttpClient可以配置连接池和证书等信息。

    HTTP请求没有什么特殊要做的这里主要说HTTPS: HTTPS请求 = 超文本传输协议HTTP + 安全套接字层SSL

    解决办法:创建自定义 ClientHttpRequestFactory

    package com.zy.cm.common.core.config;
     
    import org.springframework.http.client.SimpleClientHttpRequestFactory;
     
    import javax.net.ssl.*;
    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.security.cert.X509Certificate;
     
    /**
     * Desc: 使用Spring RestTemplete实现 Https需要自定义ClientHttpRequestFactory;
     * <p>
     * 参考链接:https://stackoverflow.com/questions/17619871/access-https-rest-service-using-spring-resttemplate
     */
    public class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory {
        @Override
        protected void prepareConnection(HttpURLConnection connection, String httpMethod) {
            try {
                if (!(connection instanceof HttpsURLConnection)) {
                    throw new RuntimeException("An instance of HttpsURLConnection is expected");
                }
     
                HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
     
                TrustManager[] trustAllCerts = new TrustManager[]{
                        new X509TrustManager() {
                            @Override
                            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                                return null;
                            }
                            @Override
                            public void checkClientTrusted(X509Certificate[] certs, String authType) {
                            }
                            @Override
                            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                            }
     
                        }
                };
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
                httpsConnection.setSSLSocketFactory(new MyCustomSSLSocketFactory(sslContext.getSocketFactory()));
     
                httpsConnection.setHostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String s, SSLSession sslSession) {
                        return true;
                    }
                });
     
                super.prepareConnection(httpsConnection, httpMethod);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     
        /**
         * We need to invoke sslSocket.setEnabledProtocols(new String[] {"SSLv3"});
         * see http://www.oracle.com/technetwork/java/javase/documentation/cve-2014-3566-2342133.html (Java 8 section)
         */
        private static class MyCustomSSLSocketFactory extends SSLSocketFactory {
     
            private final SSLSocketFactory delegate;
     
            public MyCustomSSLSocketFactory(SSLSocketFactory delegate) {
                this.delegate = delegate;
            }
     
            @Override
            public String[] getDefaultCipherSuites() {
                return delegate.getDefaultCipherSuites();
            }
     
            @Override
            public String[] getSupportedCipherSuites() {
                return delegate.getSupportedCipherSuites();
            }
     
            @Override
            public Socket createSocket(final Socket socket, final String host, final int port, final boolean autoClose) throws IOException {
                final Socket underlyingSocket = delegate.createSocket(socket, host, port, autoClose);
                return overrideProtocol(underlyingSocket);
            }
     
            @Override
            public Socket createSocket(final String host, final int port) throws IOException {
                final Socket underlyingSocket = delegate.createSocket(host, port);
                return overrideProtocol(underlyingSocket);
            }
     
            @Override
            public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort) throws
                    IOException {
                final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
                return overrideProtocol(underlyingSocket);
            }
     
            @Override
            public Socket createSocket(final InetAddress host, final int port) throws IOException {
                final Socket underlyingSocket = delegate.createSocket(host, port);
                return overrideProtocol(underlyingSocket);
            }
     
            @Override
            public Socket createSocket(final InetAddress host, final int port, final InetAddress localAddress, final int localPort) throws
                    IOException {
                final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
                return overrideProtocol(underlyingSocket);
            }
     
            private Socket overrideProtocol(final Socket socket) {
                if (!(socket instanceof SSLSocket)) {
                    throw new RuntimeException("An instance of SSLSocket is expected");
                }
                ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1"});
                return socket;
            }
        }
    }

    使用时:

        private RestTemplate restTemplate = new RestTemplate(new HttpsClientRequestFactory());

    在构造器中传入工厂类对象。

      

      

  • 相关阅读:
    matlab colormap
    张量的基本概念
    河南省测绘资质单位大全
    Meanshift算法
    图形图像的绘制 GandyDraw
    leetcode
    Java 实现装饰(Decorator)模式
    Python
    Asp.Net+Easyui实现重大CRUD
    Scriptcase演示程序,现在,他们使用SC多么简单的开发系统
  • 原文地址:https://www.cnblogs.com/xcgShare/p/13091734.html
Copyright © 2011-2022 走看看