SpringBoot将RestTemplateBuilder从1.5.14升级到2.1.5

时间:2020-05-23 17:36:22

标签: java spring spring-boot resttemplate spring-resttemplate

在使用distributed: scheduler: default-task-durations: myfunc: 1hr

的项目中,我的这段代码可以正常工作
RestTemplateBuilder 1.5.14

更新为this.restTemplate = restTemplateBuilder .setConnectTimeout(connectTimeout) .setReadTimeout(readTimeout) .requestFactory(new MyHttpComponentFactoryBuilder() .build()) .build(); 后,我得到了这段代码:

RestTemplateBuilder 2.1.5

但是在运行代码时,我有一个this.restTemplate = restTemplateBuilder .setConnectTimeout(Duration.ofMillis(connectTimeout)) .setReadTimeout(Duration.ofMillis(readTimeout)) .requestFactory(new MyHttpComponentFactoryBuilder().build().getClass()) .build(); 在删除行InvocationTargetException / NullPointerException时消失了,但是调试.requestFactory(new MyHttpComponentFactoryBuilder().build().getClass())不为空

我还尝试了建议的解决方案:

new MyHttpComponentFactoryBuilder().build().getClass()

但我还有一个... .requestFactory(new MyRequestFactorySupplier()) ... class MyRequestFactorySupplier implements Supplier<ClientHttpRequestFactory> { @Override public ClientHttpRequestFactory get() { // Using Apache HTTP client. HttpClientBuilder clientBuilder = HttpClientBuilder.create(); HttpClient httpClient = clientBuilder.build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); requestFactory.setBufferRequestBody(false); // When sending large amounts of data via POST or PUT, it is recommended to change this property to false, so as not to run out of memory. return requestFactory; } }

5 个答案:

答案 0 :(得分:3)

以下代码显示了如何为简单情况创建模板。

RestTemplate tmpl = new RestTemplateBuilder().setConnectTimeout(Duration.ofMillis(200))
                                             .setReadTimeout(Duration.ofMillis(100))
                                             .requestFactory(org.springframework.http.client.SimpleClientHttpRequestFactory.class)
                                             .build();

最好提供MyHttpComponentFactoryBuilder类的源代码。但我的建议是,创建一个扩展MyHttpComponentFactory类的类SimpleClientHttpRequestFactory,将您的代码从MyHttpComponentFactoryBuilder迁移到它。

答案 1 :(得分:2)

我已经在github wiki页面上写了详细的笔记,请确保对您有帮助

这里是示例:

        public String retrieveData(String id, String name) {

            HttpHeaders headers =createHeader();
            String requestJson = "{\"name\":\"" + name + "\"}";
            HttpEntity<String> request = new HttpEntity<String>(requestJson, headers);
            // external call time
            long startTime = System.currentTimeMillis();
            ResponseEntity<String> response = customRestTemplate().exchange(externalUrl, HttpMethod.POST, request,   
                    String.class);
            long endTime = System.currentTimeMillis();
            long duration = (endTime - startTime); // divide by 1000000 to get milliseconds.
            log.info("{\"RestTemplateDemo\":{\"id\":\"" + id + "\",\"external call duration\":" + duration + "}}");
            ObjectMapper mapper = new ObjectMapper();
            return response.getBody();
        }

答案 2 :(得分:1)

由于供应商根据需要构建ClientHttpRequestFactory,因此您在这里不再需要构建器。将RequestFactorySupplier和RestTemplateBuilder定义为bean。

    @Bean
    Supplier<ClientHttpRequestFactory> myRequestFactorySupplier() {
        return () -> {
            HttpClientBuilder clientBuilder = HttpClientBuilder.create();
            HttpClient httpClient = clientBuilder.build();
            HttpComponentsClientHttpRequestFactory requestFactory = 
                    new HttpComponentsClientHttpRequestFactory(httpClient);
            requestFactory.setConnectTimeout(5000);
            requestFactory.setReadTimeout(5000);
            requestFactory.setBufferRequestBody(false);
            return requestFactory;
        };
    }

    @Bean
    public RestTemplateBuilder restTemplateBuilder() {
        return new RestTemplateBuilder();
    }

像这样在控制器中使用工厂。

@RestController
public class TestController {

    private final RestTemplate restTemplate;

    public TestController(
            RestTemplateBuilder restTemplateBuilder,
            Supplier<ClientHttpRequestFactory> myRequestFactorySupplier
    ) {
            this.restTemplate = restTemplateBuilder                
                .requestFactory(myRequestFactorySupplier)
                .build();
    }

当然,您也可以使用专门的类。

public class MyRequestFactorySupplier implements Supplier<ClientHttpRequestFactory> {

        @Override
        public ClientHttpRequestFactory get() {
            // Using Apache HTTP client.
            HttpClientBuilder clientBuilder = HttpClientBuilder.create();
            HttpClient httpClient = clientBuilder.build();
            HttpComponentsClientHttpRequestFactory requestFactory = 
                    new HttpComponentsClientHttpRequestFactory(httpClient);
            requestFactory.setBufferRequestBody(false); // When sending large amounts of data via POST or PUT, it is recommended to change this property to false, so as not to run out of memory.
            return requestFactory;
        }

}

按照您的建议在控制器中使用它:

 public TestController(
     RestTemplateBuilder restTemplateBuilder,
     Supplier<ClientHttpRequestFactory> myRequestFactorySupplier
 ) {
     this.restTemplate = restTemplateBuilder
                .setConnectTimeout(Duration.ofMillis(5000))
                .setReadTimeout(Duration.ofMillis(5000))
                .requestFactory(new MyRequestFactorySupplier())
                .build();
 }

答案 3 :(得分:0)

尝试删除.getClass()调用,如果 .requestFactory调用指向类requestFactory(Class<? extends ClientHttpRequestFactory> requestFactory)的{​​{1}}方法,则请共享RestTemplateBuilder的代码段课

答案 4 :(得分:0)

这应该可以工作(使用lambda)

.requestFactory(() -> new MyHttpComponentFactoryBuilder().build())