Springboot restTemplate 自定义消息转换器jackson-dataformat-xml 优先生效的问题

调用第三方接口,返回中文是乱码,因此需要引入自定义消息转换器。
重新设置StringHttpMessageConverter字符集为UTF-8,解决中文乱码问题

 @Bean(name="httpClientTemplate")
    @LoadBalanced
    public RestTemplate restTemplate() {
       List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
        if (!CollectionUtils.isEmpty(converterList)) {
            HttpMessageConverter<?> converterTarget = null;
            for (HttpMessageConverter<?> item : converterList) {
                if (item.getClass() == StringHttpMessageConverter.class) {
                    converterTarget = item;
                    break;
                }
            }
            if (converterTarget != null) {
                converterList.remove(converterTarget);
                HttpMessageConverter<?> converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
                converterList.add(converter);
            }
        }

    }

但是如果同时引入了jackson-dataformat-xml包的时候,你会发现比较坑爹的现象,返回的json变xml了。
为了解决这个问题,需要更换一下优先级,把MappingJackson2XmlHttpMessageConverter放到解析器列表的最后一个。

if (converterList.get(i) instanceof MappingJackson2XmlHttpMessageConverter) {
 	Collections.swap(converterList, i, converterList.size() - 1);
}

ClientHttpRequestFactory
它是个函数式接口,用于根据URI和HttpMethod创建出一个ClientHttpRequest来发送请求。

// @since 3.0  RestTemplate这个体系都是3.0后才有的
@FunctionalInterface
public interface ClientHttpRequestFactory {	

	// 返回一个ClientHttpRequest,这样调用其execute()方法就可以发送rest请求了~
	ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException;
}

它的继承树如下:
在这里插入图片描述
可以直观的看到,我们可以使用Apache的HttpClient、OkHttp3、Netty4都可,但这些都需要额外导包,默认情况下Spring使用的是java.net.HttpURLConnection。

使用HttpClient

HttpClient可以用于发送HTTP请求,接收HTTP响应。
导包

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

配置

 @Bean
    public ClientHttpRequestFactory httpRequestFactory() {
        return new HttpComponentsClientHttpRequestFactory(httpClient());
    }

    public HttpClient httpClient(){
        // 生成默认请求配置
        RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
        // 超时时间
        requestConfigBuilder.setSocketTimeout(5000);
        // 从连接池获取连接的超时时间
        requestConfigBuilder.setConnectionRequestTimeout(20000);
        // 连接时间
        requestConfigBuilder.setConnectTimeout(5000);
        RequestConfig defaultRequestConfig = requestConfigBuilder.build();
        // 连接池配置
        // 长连接保持30秒
        final PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS);
        // 总连接数
        pollingConnectionManager.setMaxTotal(1000);
        // 同路由的并发数
        pollingConnectionManager.setDefaultMaxPerRoute(512);

        // httpclient 配置
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // 保持长连接配置,需要在头添加Keep-Alive
        httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());
        httpClientBuilder.setConnectionManager(pollingConnectionManager);
        httpClientBuilder.setDefaultRequestConfig(defaultRequestConfig);
        HttpClient client = httpClientBuilder.build();


        // 启动定时器,定时回收过期的连接
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                pollingConnectionManager.closeExpiredConnections();
                pollingConnectionManager.closeIdleConnections(5, TimeUnit.SECONDS);
            }
        }, 10 * 1000, 5 * 1000);
        return client;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值