带有休息调用的Java spring文件下载代理

时间:2018-01-11 16:34:45

标签: java file proxy resttemplate spring-rest

我需要在java中创建一个休息服务,然后连接到另一个休息服务以进行文件下载。现在,我只需要将文件从另一个后端传输到客户端,但将来会进行一些处理/转换。

对于我项目中的所有Web服务,我们使用spring rest(提供和使用服务)。

我的问题是,考虑到文件很大并且我不想遇到OutOfMemory错误,这样做的恰当方法是什么。

其他一些帖子中的人建议在两端使用流,但这真的可能吗?为此,我是否需要先将文件写入磁盘?

我目前的文件下载代码(消费者) -

public BackendResponse<byte[]> callBackendForFile(BackendRequest request) {

        String body = null;
        ResponseEntity<byte[]> responseEntity = null;
        URI uri = createURI(request);

        MultiValueMap<String, String> requestHeaders = getHeadersInfo(request.getHttpRequest());

        if (HttpMethod.GET.equals(request.getMethod())) {
            responseEntity = restTemplate.exchange(uri, request.getMethod(),
                    new HttpEntity<String>(body, requestHeaders), byte[].class);
        } else {
            LOG.error("Method:{} not supported yet", request.getMethod());
        }

        BackendResponse<byte[]> response = new BackendResponse<>();
        response.setResponse(responseEntity);
        return response;

    }

我的客户代码(提供商):

@RequestMapping(value = "/file", method = RequestMethod.GET, produces = "application/xml")
    @ResponseBody
    public void downloadFileWithoutSpring(HttpMethod method, HttpServletRequest httpRequest,
            HttpServletResponse httpResponse) {

        BackendRequest request = new BackendRequest(method,
                httpRequest.getRequestURI(), httpRequest.getQueryString(), httpRequest);

        BackendResponse<byte[]> backendResponse = dutyplanService.getFile(request);
        ResponseEntity<byte[]> response = backendResponse.getResponse();

        httpResponse.addHeader("Content-Disposition", "attachment; filename=\"" + "attachment.zip" + "\"");
        httpResponse.getOutputStream().write(response.getBody());
        httpResponse.flushBuffer();
}

注意:由于下载的附件是损坏的文件,上面的代码无法正常工作

2 个答案:

答案 0 :(得分:0)

我认为您不需要在服务器上创建该文件,只要您从另一台服务器接收到它的bytearray内容。

您可以尝试将生成注释的值更改为值application/zip(或application/octet-stream,具体取决于目标浏览器),而不是“application/xml

答案 1 :(得分:0)

您可以直接在restTemplate中传递HttpServletResponse#getOutputStream()并将其写入而无需在服务器中保存文件。

public void getFile(HttpServletResponse response) throws IOException {
        restTemplate.execute(
                "http://ip:port/temp.csv",
                HttpMethod.GET,
                null,
                clientHttpResponse -> {
                    StreamUtils.copy(clientHttpResponse.getBody(), response.getOutputStream());
                    return null;
                }
        );
    }

请注意,在调用getFile()之后,您应该像这样关闭outputStream response.getOutputStream().close()