当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在系统A->B->C之间发送文件而不将整个文件存储在B中》经验,为你挑选了1个好方法。

我有3个独立的弹簧网应用程序

A使用弹簧4.x.

B使用弹簧3.2.0

C使用弹簧4.x.

BC公开REST控制器以上载文件

一个读取文件,并上传到

B将请求发送给C而无需读取文件内容

然后C对文件做任何想做的事情.

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

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

我设法做的是: A

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 responseExtractor = new HttpMessageConverterExtractor<>(
            String.class, restTemplate.getMessageConverters());
    restTemplate.execute("http://b_url/upload", HttpMethod.POST, requestCallback, responseExtractor);
}

@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 responseExtractor = new HttpMessageConverterExtractor<>(
            String.class, restTemplate.getMessageConverters());
    restTemplate.execute("http://c_url/upload", HttpMethod.POST, requestCallback, responseExtractor);

    return "success";
}

C

@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轻松地将超过10GB的文件从A复制到C.

有了这样的解决方案,我们可以尝试在传输时停止A,B和C应该收到有关错误的通知,但有时会发生错误消息未达到C - 它因套接字超时异常而关闭,任何想法为什么会发生这种情况以及如何正确实施?

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



1> jabal..:

我会尝试在C上设置比在B上更小的套接字超时.目前它们似乎都有一些默认值,所以如果A挂起,B和C几乎都会停止获取数据.两者都开始超时,也许它是竞争条件,它取决于首先超出一次的超时精度.

推荐阅读
低调pasta_730
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有