2021-11-12   


项目需要用别的应用的接口,于是使用RestTemplate,Spring boot下配置很简单:

    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        // 连接超时
        factory.setConnectTimeout(15 * 1000);
        // 读取超时
        factory.setReadTimeout(15 * 1000);
        return factory;
    }


    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate(simpleClientHttpRequestFactory());
        // 使用StringHttpMessageConverter作为默认的转换器,这样就不用每次都设置RequestMapping中的produces属性
        restTemplate.getMessageConverters().add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }

但是发现没有请求时没有将Origin头带过去,网上查了下发现是由于**
SimpleClientHttpRequestFactory 使用了标准 JDK 工具的 ClientHttpRequestFactory 实现。
HttpUrlConnection 源码里配置了headr黑名单,Origin就在其中,https://stackoverflow.com/questions/41699608/resttemplate-not-passing-origin-header

StackOverflow上给的解决方法是设置属性允许使用受限头
通过命令行参数

-Dsun.net.http.allowRestrictedHeaders=true 

我使用的这个,代码里设置属性

System.setProperty("sun.net.http.allowRestrictedHeaders", "true");

后续使用时发现,如果请求不是200返回,restTemplate会报错:org.springframework.web.client.ResourceAccessException: I/O error on GET request

网上搜了后换了个ClientHttpRequestFactory实现:
HttpComponentsClientHttpRequestFactory 它使用 Apache HttpComponents HttpClient 创建请求。

    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory() {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        // 连接超时
        factory.setConnectTimeout(5000);
        // 数据读取超时时间,即SocketTimeout
        factory.setReadTimeout(5000);
        // 连接不够用的等待时间,不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的
        factory.setConnectionRequestTimeout(200);
        return factory;
    }

然后因为没用默认的ClientHttpRequestFactory 实现了,也不存在头限制了,之前的设置属性的代码也可以去掉了

试一下用错误的Http方法调用接口,然后报错:
org.springframework.web.client.HttpClientErrorException$MethodNotAllowed 405
这样的异常好处理多了。

Q.E.D.


我并不是什么都知道,我只是知道我所知道的。