使用 Spring Boot 和 Thymeleaf 创建文件下载 link
Creating a file download link using Spring Boot and Thymeleaf
这听起来像是一个微不足道的问题,但经过几个小时的搜索,我还没有找到答案。据我所知,问题是我正在尝试从控制器 return a FileSystemResource
并且 Thymeleaf 希望我提供 String
资源,它将使用它来呈现下一页.但是由于我正在 returning 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 link 看起来像这样:
<a th:href="${'products/download?id=' + product.id}"><span th:text="${product.name}"></span></a>
我不想被重定向到任何地方,我只需要在单击 link 后下载文件。这实际上是正确的实施吗?我不确定。
您需要将 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()));
}
Thymeleaf 有很好的文档记录,您可以在手册中找到有关 文字替换(Leandro 上面显示的内容)的信息 - section 4.7
手册摘录
<span th:text="|Welcome to our application, ${user.name}!|">
对我来说,@leandro-carracedo 的回答有效,但浏览器只会列出文件内容,而不是下载。
这修正了:
<a download="results.csv" th:href=... </a>
有一个像
这样的 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();
}
}
Thymeleaf <td><a th:href="${fileDetail.MsgFileName}" th:text="${fileDetail.MsgFileName}" /></td>
.URL 在服务器端准备,在客户端创建 href
这听起来像是一个微不足道的问题,但经过几个小时的搜索,我还没有找到答案。据我所知,问题是我正在尝试从控制器 return a FileSystemResource
并且 Thymeleaf 希望我提供 String
资源,它将使用它来呈现下一页.但是由于我正在 returning 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 link 看起来像这样:
<a th:href="${'products/download?id=' + product.id}"><span th:text="${product.name}"></span></a>
我不想被重定向到任何地方,我只需要在单击 link 后下载文件。这实际上是正确的实施吗?我不确定。
您需要将 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()));
}
Thymeleaf 有很好的文档记录,您可以在手册中找到有关 文字替换(Leandro 上面显示的内容)的信息 - section 4.7
手册摘录
<span th:text="|Welcome to our application, ${user.name}!|">
对我来说,@leandro-carracedo 的回答有效,但浏览器只会列出文件内容,而不是下载。
这修正了:
<a download="results.csv" th:href=... </a>
有一个像
这样的 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();
}
}
Thymeleaf <td><a th:href="${fileDetail.MsgFileName}" th:text="${fileDetail.MsgFileName}" /></td>
.URL 在服务器端准备,在客户端创建 href