REST服务发送损坏的文件

时间:2015-12-02 20:39:02

标签: java spring-mvc

我正在尝试创建一个将下载单词doc的java REST服务。文件下载但内容只是垃圾十六进制,而不是实际的Word文档内容。我的示例代码如下。我错过了什么?之前&在文件具有相同的字节数之后。

@SuppressWarnings("resource")
@RequestMapping(value = "get/testdoc", method=RequestMethod.GET, produces="application/octet-stream)
public @ResponseBody ResponseEntity<byte[]>  getTestDoc() throws Throwable{ 

    File doc = new File("C:\\temp\\file.doc");

    InputStream is = new FileInputStream(doc);
    byte[] bytes = IOUtils.toByteArray(is);

    HttpHeaders responseHeaders = new HttpHeaders();  
    responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    responseHeaders.set("Content-Disposition" , "Attachment; filename=file.doc");
    responseHeaders.setContentLength(ProposalDoc.length());



    return new ResponseEntity<byte[]>(bytes, responseHeaders, HttpStatus.OK);
}

4 个答案:

答案 0 :(得分:1)

我认为有两个问题:

<强> 1。长度标题:

我认为至少有一条非常奇怪的路线:

responseHeaders.setContentLength(ProposalDoc.length());

我认为应该是:

responseHeaders.setContentLength(bytes.length);

<强> 2。 @ResponseBody注释

如果您使用返回类型ResponseEntity<byte[]>,则不得添加@ResponseBody

@RequestMapping(value = "get/testdoc", method=RequestMethod.GET)
public ResponseEntity<byte[]>  getTestDoc() throws Throwable{ 
    ...
}

答案 1 :(得分:0)

尝试替换produce =&#34; application / octet-stream&#34;) with produce =&#34; application / vnd.ms-word&#34;)

答案 2 :(得分:0)

感谢所有帮助。我最终绕过了Spring&amp;将文件附加到响应,如下面的代码所示。我怀疑sprint是在幕后以某种方式转换字节。我查看了配置ByteArrayHttpMessageConverter,但这似乎没有帮助。这对我来说已经足够了。

@SuppressWarnings("resource")
@RequestMapping(value = "get/doc", method=RequestMethod.GET, produces="application/octet-stream")
   public  HttpEntity  getProposalDocs(HttpServletResponse response) throws Throwable{ 
        File doc = new File("C:\\temp\\file.doc");

        InputStream is = new FileInputStream(doc);

        response.setHeader("Content-Disposition", "attachment;filename=\"test.doc\"");
        response.setHeader("Content-Type", "application/octet-stream;");
        StreamUtils.copy(is ,response.getOutputStream());

        return new ResponseEntity(HttpStatus.OK);
    }

答案 3 :(得分:0)

Check this code also, it works fine with me.

    @RequestMapping(value = "/get/doc" , method = RequestMethod.GET , 
    produces = "application/msword")
    public ResponseEntity<InputStreamResource> getProposalDocs() throws IOException{
    ClassPathResource docfile = new ClassPathResource("file.doc");
    HttpHeaders headers

 = new HttpHeaders();
    headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
            headers.add("Pragma", "no-cache");
            headers.add("Expires", "0");
        return ResponseEntity.ok()
                .headers(headers)
                .contentLength(docfile.contentLength())
                .contentType(MediaType.parseMediaType("application/msword"))
                .body(new InputStreamResource(docfile.getInputStream()));
    }

EDITED: the idea that worked with me to return InputStreamResource instead of byte[]. Also specify the content type as produces="application/octet-stream".

This works fine with me without needed to bypass servlet response..