使用 Spring Boot 和 Thymeleaf 创建文件下载链接
Posted
技术标签:
【中文标题】使用 Spring Boot 和 Thymeleaf 创建文件下载链接【英文标题】:Creating a file download link using Spring Boot and Thymeleaf 【发布时间】:2015-07-01 04:57:05 【问题描述】:这听起来像是一个微不足道的问题,但经过数小时的搜索,我还没有找到答案。据我了解,问题是我试图从控制器返回一个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>
我不想被重定向到任何地方,我只需要在单击链接后下载文件。这实际上是正确的实现吗?我不确定。
【问题讨论】:
<a th:href="$'products/download?id=' + product.id"><span th:text="$product.name"></span></a>
开头的$
应该是@
,你可以试试吗?
如果我使用 @
,product.id
不会被实际产品 ID 替换。
因为它应该是th:href="@'products/download?id=' + $product.id"
,如documentation中所述
是的。但错误仍然存在。实际 id 现在显示在 get 请求中。
@PatrickLC 成功了!如果你把它作为答案,我会接受它。
【参考方案1】:
您需要将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()));
【讨论】:
嘿。刚才我注意到你有|
符号而不是通常的'
。有什么我应该知道的吗?
这只是连接的另一种方式,但比使用 '.检查这个答案:***.com/a/22064656/4316870
太棒了!谢谢(你的)信息! :)【参考方案2】:
有一个像
这样的 href url<a th:href="@|/download?id=$obj.id|">download</a>
然后在控制器中定义如下,将文件写入响应对象。
@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();
【讨论】:
这对我有用,第一个答案让我的屏幕上满是奇怪的字符......【参考方案3】:Thymeleaf 有很好的文档记录,您可以在手册中找到文字替换(Leandro 上面显示的内容)-section 4.7
手册摘录
<span th:text="|Welcome to our application, $user.name!|">
【讨论】:
【参考方案4】:对我来说,@leandro-carracedo 的回答有效,但浏览器只会列出文件内容,而不是下载。
这解决了:
<a download="results.csv" th:href=... </a>
【讨论】:
【参考方案5】:Thymeleaf <td><a th:href="$fileDetail.MsgFileName" th:text="$fileDetail.MsgFileName" /></td>
.URL 在服务器端准备,href 在客户端创建
【讨论】:
以上是关于使用 Spring Boot 和 Thymeleaf 创建文件下载链接的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot:在Spring Boot中使用Mysql和JPA
使用 spring boot 和 spring-boot-maven-plugin 生成战争时排除 application.properties
Spring Boot(十六):使用Jenkins部署Spring Boot
处理spring-boot-starter-quartz和spring-boot-starter-websocket同时使用报错