当前位置: 首页 > 知识库问答 >
问题:

无法发布大文件使用SpringRest模板w/自定义拦截器

鲜于玮
2023-03-14

我正在尝试使用spring rest模板POST w/自定义拦截器将一个大文件从一个微服务发布到另一个微服务,如下所示:

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, ...);

(我是否使用SimpleClientHttpask estFactory或HttpComponentsClientHttpask estFactory没有区别)

添加拦截器会在调用getRequestFactory时创建一个新的侦听ClientHttPrequestFactory(包装原始请求工厂)。

这适用于较小的文件,但适用于较大的文件-由于请求从未委托给原始请求工厂,因此不会发生流,因此会导致java。lang.OutOfMemoryError:Java堆空间异常。

任何帮助都将不胜感激。

共有2个答案

祁奇略
2023-03-14

我也遇到过这个问题,但此时切换到WebClient不是一个选项,所以我选择通过实现一个新的clienthtprequestfactory(尽管是通过abstractclienthtprequestfactorywrapper)来解决这个问题;这主要是因为我们只调整了标题,而不是正文。

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);

这就是的样子:

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。然后,您将返回一个新引入的ClientHttpRequestcreateRequest方法中的新实例。

石苏燕
2023-03-14

似乎RestTemplate的这个问题不会根据这个问题得到解决

既然WebClient已经可用,并且为流提供了一流的支持,我们就不支持这个了。

请注意,WebClient在Spring5中可用。

 类似资料:
  • null 我尝试将@priority(interceptor.priority.platform_beform)和@prematching也放入我的过滤器中,但即使是在OIDC启动后也会调用。 另外,是否有任何方法支持扩展quarkus oidc逻辑以包括自定义代码? 我无法获得oidc和keycloak-auth拦截器的优先级(知道这些可以帮助我决定过滤器的优先级)。请帮忙。

  • 我想找到一种使用JTA事务注释应用自定义拦截器的方法。 我有一个处理业务事务的方法。在这种方法中,我想: 执行一些数据库操作 使用云消息服务发布一些主题 如果其中任何一项失败,则不应执行这两项操作(即,应回滚)。 目前我使用Google Cloud pubsub作为消息服务,但该库似乎与JMS或JTA不兼容。因此,我想知道我是否可以为该库实现自定义拦截器(例如,在事务期间对消息进行排队,并在事务成

  • 拦截文件 bp CreateFileA 创建或打开文件 (32位) bp OpenFile 打开文件 (32位) bp ReadFile 读文件 (32位) bp WriteFile 写文件 (32位) bp GetPrivateProfileStringA (ini文件)

  • 我有一个Flume组件在监听Syslog流。我做了一个自定义的拦截器来修改调用,但它不起作用。我做错了什么?谢谢你,Andrea 拦截器是一个编译良好的JAR文件,位于@FLUME_HOME/bin目录中 系统将事件记录在文件中而不修改它们,这是相关的DEBUG日志:

  • 我已经创建了一个自定义的生产者拦截器(Audit病人拦截器),它接受一些自定义配置(application_id,类型等)。)。我已经从奥迪生产者拦截器项目生成了一个罐子,并将罐子放在Kafka连接中 /usr/share/java/monitoring-interceptors.当我尝试发布具有以下配置的JDBC-Source连接器时,我的审计拦截器没有被触发。 正如您在配置中看到的,我在连接器

  • 我已经构建了一个定制的gradle插件,我正试图将其发布到一个私有的maven repo。我使用插件来实现这一点。在经历了很多麻烦之后,我查看了google play services插件的实现(https://github.com/google/play-services-plugins/blob/master/google-services-plugin/publish.gradle)并试图复