首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在系统A->B->C之间发送文件,而不将整个文件存储在B中

在系统A->B->C之间发送文件,而不将整个文件存储在B中
EN

Stack Overflow用户
提问于 2015-12-07 19:11:53
回答 1查看 401关注 0票数 14

我有三个独立的spring应用程序

  • A使用Spring4.x
  • B使用Spring3.2.0
  • C使用Spring4.x

BC公开用于上传文件的REST控制器

  • A读取文件并将其上载到B
  • B将请求发送给C,而不需要读取文件内容
  • 然后C对文件做它想做的任何事情。

所以流程是A->B->C

我的问题是,能否以这样的方式设置B,以便B不会将整个文件存储在内存中,而是读取传入流并将其转发给C

我设法做到的是:A

代码语言:javascript
复制
public void sendFileFromA() throws FileNotFoundException {
    final InputStream fis = new FileInputStream(new File("someFile"));
    final RequestCallback requestCallback = new RequestCallback() {
        @Override
        public void doWithRequest(final ClientHttpRequest request) throws IOException {
            request.getHeaders().add("Content-type", "application/octet-stream");
            IOUtils.copy(fis, request.getBody());
        }
    };
    final RestTemplate restTemplate = new RestTemplate();
    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
    requestFactory.setBufferRequestBody(false);
    restTemplate.setRequestFactory(requestFactory);

    final HttpMessageConverterExtractor<String> responseExtractor = new HttpMessageConverterExtractor<>(
            String.class, restTemplate.getMessageConverters());
    restTemplate.execute("http://b_url/upload", HttpMethod.POST, requestCallback, responseExtractor);
}

B

代码语言:javascript
复制
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody String handleFileUpload(HttpServletRequest request) throws IOException {
    final ServletInputStream input = request.getInputStream();

    final RequestCallback requestCallback = new RequestCallback() {
        @Override
        public void doWithRequest(final ClientHttpRequest request) throws IOException {
            request.getHeaders().add("Content-type", "application/octet-stream");
            try (OutputStream body = request.getBody()) {
                IOUtils.copy(input, body);
            }
        }
    };
    final RestTemplate restTemplate = new RestTemplate();
    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
    requestFactory.setBufferRequestBody(false);
    restTemplate.setRequestFactory(requestFactory);

    final HttpMessageConverterExtractor<String> responseExtractor = new HttpMessageConverterExtractor<>(
            String.class, restTemplate.getMessageConverters());
    restTemplate.execute("http://c_url/upload", HttpMethod.POST, requestCallback, responseExtractor);

    return "success";
}

C

代码语言:javascript
复制
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody String handleFileUpload(HttpServletRequest request) throws IOException {
    ServletInputStream input = request.getInputStream();

    try (BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream("zibiTest"))) {
        IOUtils.copy(input, output);
    }
    return "success";
}

我可以使用B轻松地将>10 B.以上的文件从A复制到C。

使用这样的解决方案,我们可以尝试在传输时停止A,应该通知B和C错误,但有时错误消息没有到达C-它会被套接字超时异常关闭,知道为什么会发生这种情况,以及如何正确地实现它吗?

这是一个有效的方法,还是可以更好地处理?

EN

回答 1

Stack Overflow用户

发布于 2015-12-14 20:01:31

我会尝试在C上设置比B上更小的套接字超时时间。目前看来两者都有一些默认值,所以如果A挂起,B和C几乎都会同时停止获取数据。两者都开始计时,这可能是一种比赛条件,它取决于超时的准确性,其中一次首先。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34141309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档