javahttpapi调用-数据流输入和数据流输出

8yparm6h  于 2021-07-08  发布在  Java
关注(0)|答案(0)|浏览(351)

我有一个用java和springboot编写的文件传输服务,它将文件从源文件流到目标文件,而不需要任何本地存储。
它从源获取inputstream的句柄,从目标获取outputstream的句柄,并有效地执行以下操作以流式传输文件。

IOUtils.copy(inputStream, outputStream);
Destination InputStream -> IOUtils.copy -> Destination OutputStream

现在我有另一个需求,我需要调用一个加密api,它接受application/oct-ect流并返回相同的流。api在客户端提供数据时对数据进行加密,同时以流的形式返回数据。我使用以下命令使用curl测试了api:

curl -v -X POST -H "Content-Type:application/octet-stream" -H "Accept:application/octet-stream" --data-binary @test-file -o test-file.enc http://127.0.0.1:1234/encrypt/test-file

现在,我需要将此加密api与我的原始文件传输服务集成,在这里我可以获得源inputstream的句柄并将其提供给api请求,从api响应接收inputstream,然后将此插件到我的原始ioutils.copy调用中以将数据传输到目标:

Destination InputStream -> Encryption API -> Encrypted InputStream -> IOUtils.copy -> Destination OutputStream

为了最初实现加密api调用,我尝试构建一个客户机,并向fileinputstream提供信息,并将响应提取到fileoutputstream中。我试过apachehttpclient和springrestemplate。在这两种情况下,对于较小的文件,加密api都能正常工作,但是对于较大的文件,加密api只能接收部分数据,而且似乎卡在那里了。原始呼叫者(文件传输服务)没有得到任何响应,也挂起了。两种实现中的行为是相同的。
使用httpclient实现:

InputStream unencryptedInputStream = new FileInputStream("test-file");
HttpClient httpclient = HttpClients.createDefault();

URIBuilder builder = new URIBuilder("http://127.0.0.1:1234/encrypt/test-file");

HttpPost request = new HttpPost(builder.build());
request.setHeader("Content-Type", "application/octet-stream");

InputStreamEntity inputStreamEntity = new InputStreamEntity(unencryptedInputStream, 1064041488);
inputStreamEntity.setContentType("application/octet-stream");
inputStreamEntity.setChunked(true);

request.setEntity(inputStreamEntity );

HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();

InputStream encryptedInputStream = entity.getContent();

OutputStream os = new FileOutputStream("test-file.enc");
IOUtils.copy(encryptedInputStream, os);

使用spring resttemplate实现:

RestTemplate restTemplate = new RestTemplate();

InputStream unencryptedInputStream = new FileInputStream("test-file");

OutputStream encryptedOutputStream = new FileOutputStream("test-file.enc");

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
restTemplate.setRequestFactory(requestFactory);

RequestCallback requestCallback = new RequestCallback() {
    @Override
    public void doWithRequest(ClientHttpRequest clientHttpRequest) throws IOException {
        clientHttpRequest.getHeaders().add("Content-type", "application/octet-stream");
        clientHttpRequest.getHeaders().add("Accept", "application/octet-stream");

        IOUtils.copy(unencryptedInputStream, clientHttpRequest.getBody());
    }
};

ResponseExtractor<InputStream> responseExtractor = new ResponseExtractor<InputStream>() {
    @Override
    public InputStream extractData(ClientHttpResponse clientHttpResponse) throws IOException {
        IOUtils.copy(clientHttpResponse.getBody(), encryptedOutputStream);
        return clientHttpResponse.getBody();
    }
};

restTemplate.execute("http://127.0.0.1:1234/encrypt/test-file", HttpMethod.POST, requestCallback, responseExtractor);

这两种情况都适用于小文件,但挂起在大文件上。我曾尝试将请求ioutils.copy Package 在一个“runnable”线程中,但仍然存在相同的问题。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题