にファイル全体を記憶せず、私は3つの別々のスプリングのWebアプリケーションを有する送信ファイルA-> B-> C B
- がばね4.xの
- Bはスプリング3.2を使用して使用.0
- Cバネ4.xを使用
BとCは、ファイルの内容を読むために必要なしCにリクエストを送信するファイルのアップロードのためのRESTコントローラが
- がBにファイルやアップロード、それを読み込み
- Bを公開します
- 、次には、ファイルで必要なものは何でも行います。
ので、流れは以下のようになりA-> B-> C
私の質問は - それは、このような方法でセットアップBすることが可能であるので、Bは全体保管しないであろうとファイルをメモリに読み込みますが、着信ストリームを読み取ってCに転送しますか?
私は何を管理することです:
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
@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
@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";
}
私は10GB以上のファイルをAからCに簡単にコピーすることができます。
このような解決策では、転送中にAを停止しようとすると、BとCにエラーが通知されるはずですが、メッセージがCに届かない - ソケットタイムアウト例外、これがどうして起こるのか、またそれを正しく実装する方法については、クローズしてしまいますか?
これは有効なアプローチですか、それとも改善されますか?
あなたがロードする必要があるファイルを読むためには、「私の知識だけ見て問題に限定されている場合は、私が唯一の解決策のための媒体ではなくソリューションそのものであってもよいです」メモリへ。あなたがBでファイルを受け取ったら、そのファイルはすでにメモリに入っています。 – reos
ファイルをBの1つのスレッドのパイプに書き込み、次に別のスレッド(Bの場合もある)で読み取ってからCに送信します。java.nio.channels.Pipeを参照してください。 Cは受信しようとしているデータの量(httpヘッダー)を知りたいかもしれません。 –
@reosよく、ファイルの一部を読んだり、何かをしたりして、次の部分を読むことができます。 – Henry