前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RestTemplate自定义异常白名单,连接https

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

作者头像
鱼找水需要时间
发布2023-02-16 17:12:21
3370
发布2023-02-16 17:12:21
举报
文章被收录于专栏:SpringBoot教程

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依赖

代码语言:javascript
复制
 <dependency>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpclient</artifactId>
     <version>4.5.6</version>
</dependency>

自定义ErrorHandler

代码语言:javascript
复制
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

代码语言:javascript
复制
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;
    }

调用

代码语言:javascript
复制
    @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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档