无法使用带有自定义拦截器的春季休息模板发布大文件



我试图使用spring rest模板发布带有自定义拦截器的spring rest template的大型文件,如下:

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
restTemplate = new RestTemplate(requestFactory);
restTemplate.getInterceptors().add({customInterceptor});
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", {InputStreamResource});
body.add("metadata", {JSON string});
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
restTemplate.exchange({url}, HttpMethod.POST, requestEntity, ...);

(无论我使用SimpleClientHttpRequestFactory还是HttpComponentsClientHttpRequestFactory(

没有什么区别

添加拦截器会导致创建新的interceptingclienthttprequestfactory(将原始请求工厂包装在getRequestFactory上。

这适用于较小的文件,但对于大文件 - 由于请求永远不会委派给原始请求工厂,因此从未发生过流媒体,因此导致java.lang.OutOfMemoryError: Java heap space例外。

任何帮助将不胜感激。

看来,RESTTEMPLATE的问题不会根据此问题解决

现在,我们将无法支持这一点,现在可以使用网络电量并为流提供一流的支持。

请注意,WebClient可在春季5中使用。

我也遇到了这个问题,但是在此时间点,切换到WebClient不是一个选择,因此我选择通过实现新的ClientHttpRequestFactory(尽管通过AbstractClientHttpRequestFactoryWrapper(选择了工作。;它主要是因为我们只是在调整标头而不是身体。

SimpleClientHttpRequestFactory simpleRequestFactory =
    new SimpleClientHttpRequestFactory();
simpleRequestFactory.setConnectTimeout(10000);
simpleRequestFactory.setReadTimeout(60000);
simpleRequestFactory.setBufferRequestBody(false); // this enables streaming
SomeHeaderInterceptingClientHttpRequestFactory interceptingRequestFactory =
    new SomeHeaderInterceptingClientHttpRequestFactory(simpleRequestFactory);
RestTemplate restTemplate = new RestTemplate(interceptingRequestFactory);

这就是SomeHeaderInterceptingClientHttpRequestFactory的样子:

public class SomeHeaderInterceptingClientHttpRequestFactory
    extends AbstractClientHttpRequestFactoryWrapper {
    // you can have fields here that are initialized in the constructor
    // e.g. a service that supplies the header value that you want to populate
    public SomeHeaderInterceptingClientHttpRequestFactory(ClientHttpRequestFactory requestFactory) {
        super(requestFactory);
        // initialize fields
    }
    @Override
    protected ClientHttpRequest createRequest(URI uri,
                                              HttpMethod httpMethod,
                                              ClientHttpRequestFactory requestFactory)
                                              throws IOException {
        ClientHttpRequest request = requestFactory.createRequest(uri, httpMethod);
        HttpHeaders headers = request.getHeaders();
        headers.set("SOME_HEADER", "some value");
        return request;
    }
}

如果您想对身体做某事,那么您也可以尝试实现新的ClientHttpRequest。然后,您将在新引入的ClientHttpRequestFactorycreateRequest方法中返回新引入的ClientHttpRequest的新实例。

最新更新