⭐表示重要。
第一章:准备工作
- 略(基于 SpringMVC v5.3.12 的环境)。
第二章:初始形态
- 使用超链接指向要下载的文件,浏览器会尽可能的解析对应的文件,只要能在浏览器中显示的,就直接显示,而不是提示下载。
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>首页</title></head><body><a th:href="@{/download/hello.mp4}">下载 hello.mp4</a><br/><a th:href="@{/download/hello.jpg}">下载 hello.jpg</a><br/><a th:href="@{/download/hello.zip}">下载 hello.zip</a><br/></body></html>
- 上面,只有 hello.zip 文件是直接提示下载的,其他两个都是直接显示。
第三章:明确要求浏览器提示下载(⭐)
- 步骤:
- ① 设置响应头:
Content-Disposition=attachment; filename=文件名。Content-Length=文件的长度。
② 使用 IO流 将文件写出到响应流。
示例:
- 表单
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>首页</title></head><body><a th:href="@{/download}">下载</a></body></html>
- 下载
package com.github.fairy.era.mvc.handler;import org.apache.commons.io.IOUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletResponse;import java.io.File;import java.io.IOException;import java.io.InputStream;/*** @author 许大仙* @version 1.0* @since 2021-11-11 14:58*/@Controllerpublic class DownloadHandler {private final Logger logger = LoggerFactory.getLogger(this.getClass());@Autowiredprivate ServletContext servletContext;@GetMapping("/download")public void download(HttpServletResponse response) throws IOException {// 设置响应头response.setHeader("Content-Disposition", "attachment; filename=hello.jpg");File file = new File(servletContext.getRealPath("/download/hello.jpg"));response.setHeader("Content-Length", String.valueOf(file.length()));// 获取要下载的文件的输入流对象// 这里指定的路径以 Web 应用根目录为基准InputStream inputStream = servletContext.getResourceAsStream("/download/hello.jpg");IOUtils.copy(inputStream, response.getOutputStream());}}
- 示例:
- 表单
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>首页</title></head><body><a th:href="@{/download}">下载</a></body></html>
- 下载
package com.github.fairy.era.mvc.handler;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpHeaders;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Controller;import org.springframework.util.MultiValueMap;import org.springframework.web.bind.annotation.GetMapping;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletResponse;import java.io.File;import java.io.IOException;import java.io.InputStream;/*** @author 许大仙* @version 1.0* @since 2021-11-11 14:58*/@Controllerpublic class DownloadHandler {private final Logger logger = LoggerFactory.getLogger(this.getClass());@Autowiredprivate ServletContext servletContext;@GetMapping("/download")public ResponseEntity<byte[]> download(HttpServletResponse response) throws IOException {// 获取要下载的文件的输入流对象// 这里指定的路径以 Web 应用根目录为基准InputStream inputStream = servletContext.getResourceAsStream("/download/hello.jpg");try {// 2.将要下载的文件读取到字节数组中// ①获取目标文件的长度int len = inputStream.available();// ②根据目标文件长度创建字节数组byte[] buffer = new byte[len];// ③将目标文件读取到字节数组中inputStream.read(buffer);// 3.封装响应消息头// ①创建MultiValueMap接口类型的对象,实现类是HttpHeadersMultiValueMap responseHeaderMap = new HttpHeaders();// ②存入下载文件所需要的响应消息头responseHeaderMap.add("Content-Disposition", "attachment; filename=hello.jpg");File file = new File(servletContext.getRealPath("/download/hello.jpg"));responseHeaderMap.add("Content-Length", String.valueOf(file.length()));// ③创建ResponseEntity对象ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(buffer, responseHeaderMap, HttpStatus.OK);// 4.返回responseEntity对象return responseEntity;} catch (IOException e) {e.printStackTrace();} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}}return null;}}
第四章:典型应用场景
- 目前实现的是一个较为简单的下载,可以用在下面的一些场合:
- ① 零星小文件下载。
- ② 将系统内部的数据导出为 Excel、PDF 等格式,然后以下载的方式返回给用户。
