使用Spring Boot和Thymeleaf创建文件下载链接

时间:2015-04-23 07:07:42

标签: java download spring-boot thymeleaf

这听起来像是一个微不足道的问题,但经过几个小时的搜索后,我还没有找到答案。据我所知,问题是我试图从控制器返回FileSystemResource,而Thymeleaf希望我提供一个String资源,用它来渲染下一页。但由于我返回FileSystemResource,我收到以下错误:

org.thymeleaf.exceptions.TemplateInputException: Error resolving template "products/download", template might not exist or might not be accessible by any of the configured Template Resolvers

我使用的控制器映射是:

@RequestMapping(value="/products/download", method=RequestMethod.GET)
public FileSystemResource downloadFile(@Param(value="id") Long id) {
    Product product = productRepo.findOne(id);
    return new FileSystemResource(new File(product.getFileUrl()));
}

我的HTML链接看起来像这样:

<a th:href="${'products/download?id=' + product.id}"><span th:text="${product.name}"></span></a>

我不希望被重定向到任何地方,我只需要在点击链接后下载文件。这实际上是正确的实现吗?我不确定。

5 个答案:

答案 0 :(得分:9)

您需要将th:href更改为:

<a th:href="@{|/products/download?id=${product.id}|}"><span th:text="${product.name}"></span></a>

然后您还需要更改控制器并包含@ResponseBody注释:

@RequestMapping(value="/products/download", method=RequestMethod.GET)
@ResponseBody
public FileSystemResource downloadFile(@Param(value="id") Long id) {
    Product product = productRepo.findOne(id);
    return new FileSystemResource(new File(product.getFileUrl()));
}

答案 1 :(得分:1)

具有类似

的href网址
<a th:href="@{|/download?id=${obj.id}|}">download</a>

然后在In控制器中定义如下,以将文件写入响应对象。

@RequestMapping(value="/download", method=RequestMethod.GET)
public void downloadFile(@Param(value="id") Long id,HttpServletResponse response) {
        try {
            Ticket ticket = this.findById(id);
        String fileName =  Paths.get(property.getFileLocation()).resolve(ticket.getFilePath()).toString();
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        String headerKey = "Content-Disposition";
        String headerValue = String.format("attachment; filename=\"%s\"", fileName);
        response.setHeader(headerKey, headerValue);
        FileInputStream inputStream;
        try {
            inputStream = new FileInputStream(fileName);
            try {
                int c;
                while ((c = inputStream.read()) != -1) {
                response.getWriter().write(c);
                }
            } finally {
                if (inputStream != null)
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    response.getWriter().close();
            }
        } catch (IOException e) {
            e.printStackTrace();

        }
    }

答案 2 :(得分:0)

Thymeleaf有很好的文档记录,您可以在手册中找到文字替换(Leandro上面显示的内容) - section 4.7

摘自手册

<span th:text="|Welcome to our application, ${user.name}!|">

答案 3 :(得分:0)

对我来说,@ leandro-carracedo的答案有效,但浏览器只会列出文件内容,而不是下载。

此问题已解决:

<a download="results.csv" th:href=... </a>

答案 4 :(得分:0)

Thymeleaf <td><a th:href="${fileDetail.MsgFileName}" th:text="${fileDetail.MsgFileName}" /></td>.URL 在服务器端准备,在客户端创建 href