如何强制浏览器使用Spring Controller中的Application / Octet-stream标头

时间:2017-04-19 17:54:14

标签: java html spring

我有一个页面,显示文件的链接,这些文件在数据库中存储为BLOB。在多个浏览器中,其中一个链接显示内联的csv信息,而不是作为CSV文件下载。用户可以右键单击并下载,但如何将下载强制执行默认浏览器操作,因为内容类型和内容处置似乎不够。我使用的是Spring Framework的旧版本(3.2.4)。

编辑:如果我没有设置标题,则所有链接都以内嵌方式显示。 此外,设置标题后,Safari控制台中会报告下载并且未以内联方式显示的链接出现错误:

“无法加载资源:帧加载中断”

//front end code
<td><a id="downloadFile" href="<c:url value='/test/file/errors/${fileError.id}'/>" 
class=".icon-download"> 
<span class=".icon-download"></span>${fileError.filename}</a></td>

//Spring controller
@RequestMapping(value = "/test/file/errors/{id}", method = RequestMethod.GET)
  public void downloadFile(@PathVariable("id") Long id,
      HttpServletResponse response) {
    InputError file = commonService.get(InputError.class, id);
    try {
        InputStream is = new ByteArrayInputStream(file.getFile());
        IOUtils.copy(is, response.getOutputStream());
     response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getFilename() + "\"");
        response.flushBuffer();
    } catch (IOException ex) {
        throw new RuntimeException("IOError writing file to output stream");
    }

  }

3 个答案:

答案 0 :(得分:0)

您是否尝试过使用html5中的下载属性?

<td><a id="downloadFile" href="<c:url value='/test/file/errors/${fileError.id}'/>" 
class=".icon-download" download="filename_here.txt"> 
<span class=".icon-download"></span>${fileError.filename}</a></td>

答案 1 :(得分:0)

如Benoit所述,如果您可以使用HTML 5,下载选项将起作用。

然而,尽管它有点挑剔,但你现在的答案应该有效。那么在这种情况下,您是否尝试过使用适当的MIME类型的外壳?

Content-Type="application/octet-stream"

使用Spring的MediaType类的部分价值在于从代码中删除这样的“幻数”值,并确保不会发生奇怪的行为。

response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);

答案 2 :(得分:0)

如果其他人遇到同样的问题,我通过在IOUtils.copy之前设置标头来解决这个问题。

=arrayformula(sum(if($G$3:$K$3=B4,if($L$4:$L$6="Yes",$G$4:$K$6))))