zl程序教程

您现在的位置是:首页 >  后端

当前栏目

RestTemplate自定义异常白名单,连接https

异常连接HTTPS 自定义 白名单 RestTemplate
2023-06-13 09:17:02 时间

RestTemplate作为spring-web项目的一部分,在Spring 3.0版本开始被引入。

RestTemplate类通过为HTTP方法(例如GET,POST,PUT,DELETE等)提供重载的方法,提供了一种非常方便的方法访问基于HTTP的Web服务。如果你的Web服务API基于标准的RESTful风格设计,使用效果将更加的完美。

在服务生成RestTemplate的Bean时绕过SSL验证,一般情况下,会通过SimpleClientHttpRequestFactory来构建RestTemplate实例,但是它不支持https,要支持https需要替换SimpleClientHttpRequestFactory为HttpComponentsClientHttpRequestFactory,而且我们还要引入httpclient依赖

 <dependency>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpclient</artifactId>
     <version>4.5.6</version>
</dependency>

自定义ErrorHandler

import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;

/**
 * 功能:捕获RestTemplate异常
 *
 */
public class RtErrorHandler extends DefaultResponseErrorHandler {
 
    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        return super.hasError(response);
    }
 
    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode());
        // 白名单。白名单上的异常则不处理,直接返回
        List<HttpStatus> donotDeal = new ArrayList<>();
        donotDeal.add(HttpStatus.UNAUTHORIZED);

        // 非白名单则处理
        if (!donotDeal.contains(statusCode)) {
            super.handleError(response);
        }
    }
 
}

RestConfiguration

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.HttpClients;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.security.cert.X509Certificate;

@Configuration
public class RestConfiguration {


    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory, RestTemplateBuilder builder){
        RestTemplate build = builder.build();
        build.setErrorHandler(new RtErrorHandler());
        build.setRequestFactory(factory);
        return build;
    }

    @Bean
    public ClientHttpRequestFactory httpComponentsClientHttpRequestFactory() throws Exception {
        // 自定义证书校验器
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) {
                    }

                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) {
                    }

                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                }
        };

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());


        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);

        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(csf)
                .build();
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setConnectTimeout(20000);
        factory.setReadTimeout(15000);
        factory.setHttpClient(httpClient);
        return factory;
    }

调用

    @Resource
    private RestTemplate restTemplate;


    @Test
    public void main() {
    	// 定义请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("xxxx", "xxxx");
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        //  封装参数,千万不要替换为Map与HashMap,否则参数无法传递
        MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        multiValueMap.add("param", "11");

        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(multiValueMap, httpHeaders);

        String s = restTemplate.postForObject("https://xxxxx", httpEntity, String.class);
        System.out.println(s);
    }

https://blog.csdn.net/liu911025/article/details/114885299 https://blog.csdn.net/weixin_43819744/article/details/122809493