14

我的这段代码在使用的项目上运行良好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;
        }

    }

但我也有一个InvocationTargetException / NullPointerException

4

5 回答 5

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

于 2020-05-26T07:00:58.690 回答
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();
        }
于 2020-06-01T04:46:12.700 回答
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();
 }

于 2020-05-31T22:46:28.077 回答
0

这应该有效(使用 lambda)

.requestFactory(() -> new MyHttpComponentFactoryBuilder().build())
于 2020-05-26T08:29:21.113 回答
0

尝试删除.getClass()调用,如果.requestFactory 调用指向类的requestFactory(Class<? extends ClientHttpRequestFactory> requestFactory)方法,RestTemplateBuilder那么请分享你的MyHttpComponentFactoryBuilder类的代码片段

于 2020-05-26T06:42:05.290 回答