【问题标题】:Receive file stream through REST web service ResponseEntity<byte[]>通过 REST Web 服务 ResponseEntity<byte[]> 接收文件流
【发布时间】:2016-03-20 00:01:05
【问题描述】:

我编写了一个方法来通过 REST Web 服务将文件作为字节数组发送,并且在客户端我想以流的形式接收这个文件(客户端是一个使用 java 代码的 matlab 应用程序)。 当我发送的文件也超过 300MB 时,我在 matlab 上收到堆错误,因为堆内存设置为 356MB,而不是在 eclipse 中为 1024MB。是否可以将流用于接收到的 ResponseEntity 以便一次存储每个字节?或者我必须在 1024 上增加 Matlab 堆内存?我在服务器上有这段代码:

@Override
@RequestMapping(value = "/file", method = RequestMethod.GET) 
public  ResponseEntity<byte[]> getAcquisition(HttpServletResponse resp,@RequestParam(value="filePath", required = true) String filePath){
    final HttpHeaders headers = new HttpHeaders();
    OutputStream outputStream = null;
    File toServeUp= null;
    try{
        toServeUp=new File(filePath);
        if (!toServeUp.exists()){
            headers.setContentType(MediaType.TEXT_PLAIN);
            LOG.error("Threw exception in MatlabClientControllerImpl::getAcquisition : File doesn't exists!!");
            String message = "ERROR: Could not retrieve file on server, check the path!";       
            return new ResponseEntity<byte[]>(message.getBytes(Charset.forName("UTF-8")), headers, HttpStatus.OK);
        }else{
            try(InputStream inputStream = new FileInputStream(toServeUp);) {
                resp.setContentType("application/octet-stream"); 
                resp.setHeader("Content-Disposition", "attachment; filename=\""+toServeUp.getName()+"\"");
                Long fileSize = toServeUp.length();
                resp.setContentLength(fileSize.intValue());
                outputStream = resp.getOutputStream();
                byte[] buffer = new byte[1024];
                int read = 0;
                while ((read = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, read);
                }
                headers.setContentType(MediaType.TEXT_PLAIN);
                return new ResponseEntity<byte[]>("ok".getBytes(), headers, HttpStatus.OK);
            }
            catch (Exception e) {
                headers.setContentType(MediaType.TEXT_PLAIN);
                ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
                LOG.error("Threw exception in MatlabClientControllerImpl::getAcquisition :" + errorResponse.getStacktrace());
                String message = "ERROR: Could not send file!";     
                return new ResponseEntity<byte[]>(message.getBytes(("UTF-8")), headers, HttpStatus.OK);
            }finally{
                //close the streams to prevent memory leaks
                try {
                    if (outputStream!=null){
                        outputStream.flush();
                        outputStream.close();           
                    }
                } catch (IOException e) {
                    headers.setContentType(MediaType.TEXT_PLAIN);
                    ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
                    LOG.error("Threw exception in MatlabClientControllerImpl::getAcquisition :" + errorResponse.getStacktrace());
                    String message = "ERROR: Could not close stream.!";     
                    return new ResponseEntity<byte[]>(message.getBytes("UTF-8"), headers, HttpStatus.OK);
                }
            }   
        }
    }catch(Exception e){
        headers.setContentType(MediaType.TEXT_PLAIN);
        ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
        LOG.error("Threw exception in MatlabClientControllerImpl::getAcquisition :" + errorResponse.getStacktrace());
        String message = "ERROR: Error in the path, check it!";     
        return new ResponseEntity<byte[]>(message.getBytes(), headers, HttpStatus.OK);
    }
}

在我拥有的客户端上:

@Override
    public Response getFile(String serverIp, String toStorePath, String filePath){
        ResponseEntity<byte[]> responseEntity = null;
        try{
            RestTemplate restTemplate = new RestTemplate();
            responseEntity  = restTemplate.getForEntity(serverIp + "ATS/client/file/?filePath={filePath}", byte[].class, filePath); 

            if (MediaType.TEXT_PLAIN.toString().equals(responseEntity.getHeaders().getContentType().toString()))
                return new Response(false, false, new String(responseEntity.getBody(),Charset.forName("UTF-8")), null);
            else{
                Path p = Paths.get(filePath);
                String fileName = p.getFileName().toString();
                FileOutputStream fos = new FileOutputStream(toStorePath+"\\"+ fileName);
                fos.write(responseEntity.getBody());
                fos.close();
                return new Response(true, true, "Your file has been downloaded!", null);
            }
        }catch(Exception e){
            ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
            return new Response(false, false, "Error on the client side!" , errorResponse);
        }
    }

实际上,所有文件都在responseEntity 中,它会抛出堆异常。 谢谢,最好的问候

【问题讨论】:

    标签: java matlab file rest stream


    【解决方案1】:

    您可以使用 setBufferRequestBody(false) 依次生成一个 StreamingClientHttpRequest,它在调用 getBody() 时打开连接。

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

    在那之后,我认为只使用 FileSystemResource 作为您的请求正文会做正确的事情。

    【讨论】:

    • 也许我不太了解。我使用RestTemplate restTemplate = new RestTemplate(); SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setBufferRequestBody(false); restTemplate.setRequestFactory(requestFactory); responseEntity = restTemplate.getForEntity(serverIp + "ATS/client/file/?filePath={filePath}", byte[].class, filePath); 但收到同样的错误
    猜你喜欢
    • 2014-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 2015-04-25
    相关资源
    最近更新 更多