1. 程式人生 > 其它 >RestTemplate訪問ip地址報錯解決

RestTemplate訪問ip地址報錯解決

技術標籤:開發記錄javaspring bootresttemplatehttps介面

RestTemplate訪問https+ip地址報錯解決

最近專案需要訪問指定介面,由ip地址+埠構成,準備使用spring的RestTemplate。測試後發現報錯

No subject alternative names present

在大量的查閱資料後(baidu),我瞭解了https是不能直接使用ip地址訪問介面的,需要使用域名,但是該介面目前又沒有域名,那該怎麼解決呢?

我又查詢了大量的資料(baidu),找到了解決辦法,如下:
建立一個HttpClientUtils類,該類的主要作用就是設定RestTemplate,使其不會對域名檢查,這個原理目前我也沒搞懂,但是你只要知道,這麼設定就可以https訪問ip就行了哈哈。

package com.cdxc.modules.clzysync.utils;

import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.ssl.SSLContextBuilder; import org.apache.
http.ssl.TrustStrategy; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; public class HttpClientUtils { /* * https ip地址請求忽略證書設定 * * */ public static CloseableHttpClient acceptsUntrustedCertsHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { HttpClientBuilder b = HttpClientBuilder.create(); // setup a Trust Strategy that allows all certificates. // SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { @Override public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { return true; } }).build(); b.setSSLContext(sslContext); // don't check Hostnames, either. // -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; // here's the special part: // -- need to create an SSL Socket Factory, to use our weakened "trust strategy"; // -- and create a Registry, to register it. // SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", sslSocketFactory) .build(); // now, we create connection-manager using our Registry. // -- allows multi-threaded use PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry); connMgr.setMaxTotal(200); connMgr.setDefaultMaxPerRoute(100); b.setConnectionManager( connMgr); // finally, build the HttpClient; // -- done! CloseableHttpClient client = b.build(); return client; } }

接下來,在SpringBoot配置類中呼叫該例項,程式碼如下:

import com.cdxc.modules.clzysync.utils.HttpClientUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

/**
 * RestTemplate配置類
 */
@Configuration
public class RestTemplateConfiguration {

   /* @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        return new RestTemplate(factory);
    }*/

    @Bean
    public RestTemplate httpsRestTemplate(HttpComponentsClientHttpRequestFactory httpsFactory){
        RestTemplate restTemplate = new RestTemplate(httpsFactory);
        restTemplate.setErrorHandler(new ResponseErrorHandler() {
            @Override
            public boolean hasError(ClientHttpResponse clientHttpResponse) {
                return false;
            }

            @Override
            public void handleError(ClientHttpResponse clientHttpResponse) {
                //預設處理非200的返回,會拋異常
            }
        });
        return restTemplate;
    }

    @Bean(name = "httpsFactory")
    public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory() throws Exception{
        CloseableHttpClient httpClient = HttpClientUtils.acceptsUntrustedCertsHttpClient();
        HttpComponentsClientHttpRequestFactory httpsFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        httpsFactory.setReadTimeout(2000);
        httpsFactory.setConnectTimeout(2000);
        return httpsFactory;
    }

上面步驟完成之後,直接呼叫RestTemplate就行了,如下:

    @Autowired
    private RestTemplate restTemplate;

好了,所有工作完成,可以隨意訪問了

--------------{"success":true,"msg":"請求成功","data":{"deviceId":"xxxxxxx"},"time":10}