1.用IDEA创建名叫springboot-file的SpringBoot项目,并将Package name 改为com.example.springboot,导入Spring Web和thymeleaf依赖。(定制软件如果创建过程中遇到了问题,定制软件可以看我写的文章《》定制软件中前三个步骤。)
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-thymeleaf</artifactId>
- </dependency>
2.定制软件文件上传分为单文件上定制软件传和多文件上传,定制软件这里通过一个方法实现。在src/main/resources/templates定制软件文件下创建upload.html文件。
- <!DOCTYPE html>
- <html xmlns:th="http://www.thymeleaf.org">
- <head>
-
- </head>
-
- <body>
- <form th:action="@{/upload}" method="post" enctype="multipart/form-data">
- 定制软件选择单个文件<input type="file" name="file"><br><br>
- 定制软件选择多个文件<input type="file" name="files" multiple><br><br>
- <input type="submit" value="上传">
- </form>
- </body>
-
- </html>
3.在src/main/resources文件下的application.properties文件中,定制软件添加文件保存的路径。
filePath=E:/springboot_save_file/
4.在src/main/resources的com.example.springboot文件夹下,创建包controller,并创建FileController类,定制软件用于处理所有的文件上定制软件传和下载请求。(定制软件由于下载页面还没写,定制软件所以上传文件完成后,会报404错误,定制软件但是不影响功能)
- package com.example.springboot.controller;
-
- import cn.hutool.extra.servlet.ServletUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.*;
- import org.springframework.web.multipart.MultipartFile;
-
- import javax.servlet.http.HttpServletResponse;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.nio.CharBuffer;
- import java.nio.charset.Charset;
- import java.nio.charset.CharsetEncoder;
- import java.util.List;
-
- @Controller
- public class FileController {
- //读取application.properties文件中的filePath属性
- @Value("${filePath}")
- private String filePath;
-
- /**
- * 定制软件前往上传页面
- * @return 页面名称
- */
- @GetMapping({"/upload", ""})
- public String goIndex() {
- return "upload";
- }
-
- /**
- * 定制软件将文件保存到指定文件夹
- * @param file 单个文件
- * @param files 多个文件
- * @return 重定向到controller定制软件层中定制软件前往下载页面的url
- * @throws IOException
- */
- @PostMapping("/upload")
- public String uploadAndGoDownLoad(@RequestPart("file") MultipartFile file,
- @RequestPart("files") List<MultipartFile> files) throws IOException {
-
-
- //定制软件定制软件判断文件夹是否存在,不存在时,定制软件创建文件夹
- File directoryFile = new File(filePath);
- if (!directoryFile.exists()) {
- //定制软件创建多个文件夹
- directoryFile.mkdirs();
- }
-
- //定制软件判断文件是否为空,不为空时,保存文件
- if (!file.isEmpty()) {
- saveFile(file);
- }
-
- //定制软件判断上传文件个数是否为0
- if (files.size() > 0) {
- for (MultipartFile multipartFile : files) {
- if (!multipartFile.isEmpty()) {
- saveFile(multipartFile);
- }
- }
- }
- return "redirect:/goDownload";
- }
-
- /**
- * 定制软件保存所有的所有上传的文件名称,前往下载页面
- * @param model
- * @return 页面名称
- */
- @GetMapping("/goDownload")
- public String goDownload(Model model) {
- File file = new File(filePath);
- //判断文件夹是否存在
- if (file.exists()) {
- //获取文件夹下面的所有名称
- String[] list = file.list();
- model.addAttribute("fileNames", list);
- }
-
- return "download";
- }
-
- /**
- * 保存文件到指定位置
- * @param file 需要上传的文件
- * @throws IOException
- */
- public void saveFile(MultipartFile file) throws IOException {
- //获取文件名
- String name = file.getOriginalFilename();
- file.transferTo(new File(filePath + name));
- }
- }
注意:
1.前端向后端传递的form表单enctype属性的值必须"multipart/form-data。
2.前后端请求方式要一致,且必须为post。
3.@RequestPart注解最好加上,但是不加也可以。注意前后端参数的绑定,对于注解的使用,可以查看我写的《》。
结果:
5.对于文件上传功能,相对较为简单,这里就不具体说了。下面会具体介绍文件下载,前后端实现方式和注意的地方。文件下载和文件上传是连在一起的,都写在了FileController类中。首先前端写采用最简单的方式,实现文件下载,将后端实现方式讲完后,再讲其他前端实现方式。
- <!DOCTYPE html>
- <html xmlns:th="http://www.thymeleaf.org">
-
- <head>
- <script>
- function downloadFileByOpen(fileName) {
- window.open("http://localhost:8080/download/hutool?fileName=" + fileName);
- }
- </script>
- </head>
-
- <body>
- <h3>后端hutool + 前端open方式</h3>
- <div th:if="${fileNames} == null">没有文件可下载</div>
- <ul>
- <li th:each="fileName : ${fileNames}" th:text="${fileName} + ' 下载'" th:onclick="downloadFileByOpen([[${fileName}]])">
- </li>
- </ul>
-
-
- </body>
-
- </html>
6.后端实现文件下载方式一:hutool方式。在pom.xml文件中导入hutool-extra的依赖,并设置CharacterEncoding为UTF-8。如果不设置CharacterEncoding,会出现中文文件名乱码。
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-extra</artifactId>
- <version>5.8.8</version>
- </dependency>
- package com.example.springboot.controller;
-
- import cn.hutool.extra.servlet.ServletUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.*;
- import org.springframework.web.multipart.MultipartFile;
-
- import javax.servlet.http.HttpServletResponse;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.nio.CharBuffer;
- import java.nio.charset.Charset;
- import java.nio.charset.CharsetEncoder;
- import java.util.List;
-
- @Controller
- public class FileController {
- //读取application.properties文件中的filePath属性
- @Value("${filePath}")
- private String filePath;
-
- /**
- * 前往上传页面
- * @return 页面名称
- */
- @GetMapping({"/upload", ""})
- public String goIndex() {
- return "upload";
- }
-
- /**
- * 将文件保存到指定文件夹
- * @param file 单个文件
- * @param files 多个文件
- * @return 重定向到controller层中前往下载页面的url
- * @throws IOException
- */
- @PostMapping("/upload")
- public String uploadAndGoDownLoad(@RequestPart("file") MultipartFile file,
- @RequestPart("files") List<MultipartFile> files) throws IOException {
-
-
- //判断文件夹是否存在,不存在时,创建文件夹
- File directoryFile = new File(filePath);
- if (!directoryFile.exists()) {
- //创建多个文件夹
- directoryFile.mkdirs();
- }
-
- //判断文件是否为空,不为空时,保存文件
- if (!file.isEmpty()) {
- saveFile(file);
- }
-
- //判断上传文件个数是否为0
- if (files.size() > 0) {
- for (MultipartFile multipartFile : files) {
- if (!multipartFile.isEmpty()) {
- saveFile(multipartFile);
- }
- }
- }
- return "redirect:/goDownload";
- }
-
- /**
- * 保存所有的所有上传的文件名称,前往下载页面
- * @param model
- * @return 页面名称
- */
- @GetMapping("/goDownload")
- public String goDownload(Model model) {
- File file = new File(filePath);
- //判断文件夹是否存在
- if (file.exists()) {
- //获取文件夹下面的所有名称
- String[] list = file.list();
- model.addAttribute("fileNames", list);
- }
-
- return "download";
- }
-
- /**
- * 使用Hutool实现文件下载
- * @param fileName 要下载的文件名
- * @param response
- */
- @GetMapping("/download/hutool")
- @ResponseBody
- public void downloadByHutool(@RequestParam(value = "fileName") String fileName,
- HttpServletResponse response) {
- //防止中文乱码
- response.setCharacterEncoding("UTF-8");
- ServletUtil.write(response,new File(filePath + fileName));
- }
-
- /**
- * 保存文件到指定位置
- * @param file 需要上传的文件
- * @throws IOException
- */
- public void saveFile(MultipartFile file) throws IOException {
- //获取文件名
- String name = file.getOriginalFilename();
- file.transferTo(new File(filePath + name));
- }
- }
7.后端实现方式二:通过查看Hutool源码,自己模仿着源码写的一种方式。将前端download.html文件中,添加方式二的测试。后端添加方式二的实现代码
- <!DOCTYPE html>
- <html xmlns:th="http://www.thymeleaf.org">
-
- <head>
- <script>
- function downloadFileByOpen(fileName) {
- window.open("http://localhost:8080/download/hutool?fileName=" + fileName);
- }
- function downloadFileByOpenAndSelf(fileName) {
- window.open("http://localhost:8080/download/hutool/self?fileName=" + fileName);
- }
- </script>
- </head>
-
- <body>
- <h3>后端hutool + 前端open方式</h3>
- <div th:if="${fileNames} == null">没有文件可下载</div>
- <ul>
- <li th:each="fileName : ${fileNames}" th:text="${fileName} + ' 下载'" th:onclick="downloadFileByOpen([[${fileName}]])">
- </li>
- </ul>
- <br>
- <br>
-
- <h3>后端模仿hutool + 前端open方式</h3>
- <div th:if="${fileNames} == null">没有文件可下载</div>
- <ul>
- <li th:each="fileName : ${fileNames}" th:text="${fileName} + ' 下载'" th:onclick="downloadFileByOpenAndSelf([[${fileName}]])">
- </li>
- </ul>
-
- </body>
-
- </html>
- package com.example.springboot.controller;
-
- import cn.hutool.extra.servlet.ServletUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.*;
- import org.springframework.web.multipart.MultipartFile;
-
- import javax.servlet.http.HttpServletResponse;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.nio.CharBuffer;
- import java.nio.charset.Charset;
- import java.nio.charset.CharsetEncoder;
- import java.util.List;
-
- @Controller
- public class FileController {
- //读取application.properties文件中的filePath属性
- @Value("${filePath}")
- private String filePath;
-
- /**
- * 前往上传页面
- * @return 页面名称
- */
- @GetMapping({"/upload", ""})
- public String goIndex() {
- return "upload";
- }
-
- /**
- * 将文件保存到指定文件夹
- * @param file 单个文件
- * @param files 多个文件
- * @return 重定向到controller层中前往下载页面的url
- * @throws IOException
- */
- @PostMapping("/upload")
- public String uploadAndGoDownLoad(@RequestPart("file") MultipartFile file,
- @RequestPart("files") List<MultipartFile> files) throws IOException {
-
-
- //判断文件夹是否存在,不存在时,创建文件夹
- File directoryFile = new File(filePath);
- if (!directoryFile.exists()) {
- //创建多个文件夹
- directoryFile.mkdirs();
- }
-
- //判断文件是否为空,不为空时,保存文件
- if (!file.isEmpty()) {
- saveFile(file);
- }
-
- //判断上传文件个数是否为0
- if (files.size() > 0) {
- for (MultipartFile multipartFile : files) {
- if (!multipartFile.isEmpty()) {
- saveFile(multipartFile);
- }
- }
- }
- return "redirect:/goDownload";
- }
-
- /**
- * 保存所有的所有上传的文件名称,前往下载页面
- * @param model
- * @return 页面名称
- */
- @GetMapping("/goDownload")
- public String goDownload(Model model) {
- File file = new File(filePath);
- //判断文件夹是否存在
- if (file.exists()) {
- //获取文件夹下面的所有名称
- String[] list = file.list();
- model.addAttribute("fileNames", list);
- }
-
- return "download";
- }
-
- /**
- * 使用Hutool实现文件下载
- * @param fileName 要下载的文件名
- * @param response
- */
- @GetMapping("/download/hutool")
- @ResponseBody
- public void downloadByHutool(@RequestParam(value = "fileName") String fileName,
- HttpServletResponse response) {
- //防止中文乱码
- response.setCharacterEncoding("UTF-8");
- ServletUtil.write(response,new File(filePath + fileName));
- }
-
- /**
- * 模仿hutool实现文件下载
- * @param fileName 要下载的文件名
- * @param response
- * @throws IOException
- */
- @GetMapping("/download/hutool/self")
- @ResponseBody
- public void downloadBySelfAndHutool(@RequestParam(value = "fileName") String fileName,
- HttpServletResponse response) throws IOException {
-
- //设置字符编码
- response.setCharacterEncoding("UTF-8");
-
- //以下模仿hutool进行相应设置
- //设置内容类型
- response.setHeader("Content-Type", "application/octet-stream");
- //设置文件名,是解决中文乱码的关键
- response.setHeader("Content-Disposition", String.format("attachment;filename=\"%s\"", URLEncoder.encode(fileName,"UTF-8")));
-
- //将文件取出,并写到response
- FileInputStream fileInputStream = new FileInputStream(filePath + fileName);
- OutputStream outputStream = response.getOutputStream();
- byte[] bytes = new byte[1024];
- int length;
- while ((length = fileInputStream.read(bytes)) != -1) {
- outputStream.write(bytes, 0, length);
- }
- fileInputStream.close();
- outputStream.flush();
- outputStream.close();
- }
-
- /**
- * 保存文件到指定位置
- * @param file 需要上传的文件
- * @throws IOException
- */
- public void saveFile(MultipartFile file) throws IOException {
- //获取文件名
- String name = file.getOriginalFilename();
- file.transferTo(new File(filePath + name));
- }
- }
8.上面两种后端实现文件下载方式,对于前端来说,无论是通过open方式,还是通过方式都可以使用。下面这种是通过返回值方式,这种方式主要用于前后端分离项目中。下面以原生的Ajax,模拟前后端分离项目,介绍前后端的实现方式。
download.html中添加Ajax和返回值方式实现文件下载的测试。
- <!DOCTYPE html>
- <html xmlns:th="http://www.thymeleaf.org">
-
- <head>
- <script>
- function downloadFileByOpen(fileName) {
- window.open("http://localhost:8080/download/hutool?fileName=" + fileName);
- }
- function downloadFileByOpenAndSelf(fileName) {
- window.open("http://localhost:8080/download/hutool/self?fileName=" + fileName);
- }
- function downloadFileByAjax(fileName) {
- let xhr = new XMLHttpRequest;
- xhr.open("get","/download/return?fileName=" + fileName,true);
- //发送请求
- xhr.send();
- xhr.responseType="blob";
- xhr.onload = function() {
- if(this.status === 200) {
- let blob = new Blob([this.response]);
- let elink = document.createElement('a');
- elink.download = fileName;
- elink.style.display = 'none';
- elink.href = URL.createObjectURL(blob);
- document.body.appendChild(elink);
- elink.click();
- // 释放URL 对象
- URL.revokeObjectURL(elink.href);
- document.body.removeChild(elink);
- }
- }
- }
- </script>
- </head>
-
- <body>
- <h3>后端hutool + 前端open方式</h3>
- <div th:if="${fileNames} == null">没有文件可下载</div>
- <ul>
- <li th:each="fileName : ${fileNames}" th:text="${fileName} + ' 下载'"
- th:onclick="downloadFileByOpen([[${fileName}]])">
- </li>
- </ul>
- <br>
- <br>
-
- <h3>后端模仿hutool + 前端open方式</h3>
- <div th:if="${fileNames} == null">没有文件可下载</div>
- <ul>
- <li th:each="fileName : ${fileNames}" th:text="${fileName} + ' 下载'"
- th:onclick="downloadFileByOpenAndSelf([[${fileName}]])">
- </li>
- </ul>
- <br>
- <br>
-
- <h3>后端返回值 + 前端Ajax方式</h3>
- <div th:if="${fileNames} == null">没有文件可下载</div>
- <ul>
- <li th:each="fileName : ${fileNames}" th:text="${fileName} + ' 下载'"
- th:onclick="downloadFileByAjax([[${fileName}]])">
- </li>
- </ul>
- </body>
-
- </html>
FileController类中添加返回值方式实现文件上传的代码。(FileController类最终代码)
- package com.example.springboot.controller;
-
- import cn.hutool.extra.servlet.ServletUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.*;
- import org.springframework.web.multipart.MultipartFile;
-
- import javax.servlet.http.HttpServletResponse;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.nio.CharBuffer;
- import java.nio.charset.Charset;
- import java.nio.charset.CharsetEncoder;
- import java.util.List;
-
- @Controller
- public class FileController {
- //读取application.properties文件中的filePath属性
- @Value("${filePath}")
- private String filePath;
-
- /**
- * 前往上传页面
- * @return 页面名称
- */
- @GetMapping({"/upload", ""})
- public String goIndex() {
- return "upload";
- }
-
- /**
- * 将文件保存到指定文件夹
- * @param file 单个文件
- * @param files 多个文件
- * @return 重定向到controller层中前往下载页面的url
- * @throws IOException
- */
- @PostMapping("/upload")
- public String uploadAndGoDownLoad(@RequestPart("file") MultipartFile file,
- @RequestPart("files") List<MultipartFile> files) throws IOException {
-
-
- //判断文件夹是否存在,不存在时,创建文件夹
- File directoryFile = new File(filePath);
- if (!directoryFile.exists()) {
- //创建多个文件夹
- directoryFile.mkdirs();
- }
-
- //判断文件是否为空,不为空时,保存文件
- if (!file.isEmpty()) {
- saveFile(file);
- }
-
- //判断上传文件个数是否为0
- if (files.size() > 0) {
- for (MultipartFile multipartFile : files) {
- if (!multipartFile.isEmpty()) {
- saveFile(multipartFile);
- }
- }
- }
- return "redirect:/goDownload";
- }
-
- /**
- * 保存所有的所有上传的文件名称,前往下载页面
- * @param model
- * @return 页面名称
- */
- @GetMapping("/goDownload")
- public String goDownload(Model model) {
- File file = new File(filePath);
- //判断文件夹是否存在
- if (file.exists()) {
- //获取文件夹下面的所有名称
- String[] list = file.list();
- model.addAttribute("fileNames", list);
- }
-
- return "download";
- }
-
- /**
- * 使用Hutool实现文件下载
- * @param fileName 要下载的文件名
- * @param response
- */
- @GetMapping("/download/hutool")
- @ResponseBody
- public void downloadByHutool(@RequestParam(value = "fileName") String fileName,
- HttpServletResponse response) {
- //防止中文乱码
- response.setCharacterEncoding("UTF-8");
- ServletUtil.write(response,new File(filePath + fileName));
- }
-
- /**
- * 模仿hutool实现文件下载
- * @param fileName 要下载的文件名
- * @param response
- * @throws IOException
- */
- @GetMapping("/download/hutool/self")
- @ResponseBody
- public void downloadBySelfAndHutool(@RequestParam(value = "fileName") String fileName,
- HttpServletResponse response) throws IOException {
-
- //设置字符编码
- response.setCharacterEncoding("UTF-8");
-
- //以下模仿hutool进行相应设置
- //设置内容类型
- response.setHeader("Content-Type", "application/octet-stream");
- //设置文件名,是解决中文乱码的关键
- response.setHeader("Content-Disposition", String.format("attachment;filename=\"%s\"", URLEncoder.encode(fileName,"UTF-8")));
-
- //将文件取出,并写到response
- FileInputStream fileInputStream = new FileInputStream(filePath + fileName);
- OutputStream outputStream = response.getOutputStream();
- byte[] bytes = new byte[1024];
- int length;
- while ((length = fileInputStream.read(bytes)) != -1) {
- outputStream.write(bytes, 0, length);
- }
- fileInputStream.close();
- outputStream.flush();
- outputStream.close();
- }
-
- /**
- * 通过返回值方式,实现文件下载
- * @param fileName 文件名
- * @return 文件流和请求头信息
- * @throws IOException
- */
- @GetMapping("/download/return")
- @ResponseBody
- public ResponseEntity<InputStreamResource> download(@RequestParam(value = "fileName") String fileName) throws IOException {
- // 读取文件
- String path = filePath + fileName;
- FileSystemResource file = new FileSystemResource(path);
-
- // 设置响应头
- HttpHeaders headers = new HttpHeaders();
- headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getFilename()));
-
- return ResponseEntity
- .ok()
- .headers(headers)
- .contentLength(file.contentLength())
- .contentType(MediaType.parseMediaType("application/octet-stream"))
- .body(new InputStreamResource(file.getInputStream()));
- }
-
- /**
- * 保存文件到指定位置
- * @param file 需要上传的文件
- * @throws IOException
- */
- public void saveFile(MultipartFile file) throws IOException {
- //获取文件名
- String name = file.getOriginalFilename();
- file.transferTo(new File(filePath + name));
- }
- }
注意:
1.前端采用原生的ajax实现的,responseType最好设置为blob(设置为arraybuffer也可以,就是增加转换为blob的步骤)。(开始打算用jQuery中的ajax,但是设置responseType为blob会报错。查找原因,也解决不了。一般这种后端实现方式,对应的是前后端分离项目,然后前端使用的axios。我的能力也有限,知道解决方式的可以评论区留言,一起进步。
报错:jquery.js:10287 Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'blob').)
2.查看后端代码可以发现,这种下载文件的方式,我们不用去考虑中文乱码问题了。
9.前端使用,后端继续使用返回值方式,实现文件下载功能。以下是download.html最终代码。后端代码没有改变。这种前后端配合方式实现文件下载,在前后端分离项目中应用广泛(尤其在vue+springboot前后端组合中)。
- <!DOCTYPE html>
- <html xmlns:th="http://www.thymeleaf.org">
-
- <head>
- <!-- 导入axios -->
- <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
- <script>
- function downloadFileByOpen(fileName) {
- window.open("http://localhost:8080/download/hutool?fileName=" + fileName);
- }
- function downloadFileByOpenAndSelf(fileName) {
- window.open("http://localhost:8080/download/hutool/self?fileName=" + fileName);
- }
- function downloadFileByAjax(fileName) {
- let xhr = new XMLHttpRequest;
- xhr.open("get", "/download/return?fileName=" + fileName, true);
- //发送请求
- xhr.send();
- xhr.responseType = "blob";
- xhr.onload = function () {
- if (this.status === 200) {
- let blob = new Blob([this.response]);
- let elink = document.createElement('a');
- elink.download = fileName;
- elink.style.display = 'none';
- elink.href = URL.createObjectURL(blob);
- document.body.appendChild(elink);
- elink.click();
- // 释放URL 对象
- URL.revokeObjectURL(elink.href);
- document.body.removeChild(elink);
- }
- }
- }
- function downloadFileByAxios(fileName) {
- axios({
- url: "/download/return",
- method: "get",
- responseType: "blob",
- params: {
- fileName
- }
- }).then(function (res) {
- console.log(res);
- let blob = new Blob([res.data]);
- let elink = document.createElement('a');
- elink.download = fileName;
- elink.style.display = 'none';
- elink.href = URL.createObjectURL(blob);
- document.body.appendChild(elink);
- elink.click();
- // 释放URL 对象
- URL.revokeObjectURL(elink.href);
- document.body.removeChild(elink);
- })
- }
- </script>
- </head>
-
- <body>
- <h3>后端hutool + 前端open方式</h3>
- <div th:if="${fileNames} == null">没有文件可下载</div>
- <ul>
- <li th:each="fileName : ${fileNames}" th:text="${fileName} + ' 下载'"
- th:onclick="downloadFileByOpen([[${fileName}]])">
- </li>
- </ul>
- <br>
- <br>
-
- <h3>后端模仿hutool + 前端open方式</h3>
- <div th:if="${fileNames} == null">没有文件可下载</div>
- <ul>
- <li th:each="fileName : ${fileNames}" th:text="${fileName} + ' 下载'"
- th:onclick="downloadFileByOpenAndSelf([[${fileName}]])">
- </li>
- </ul>
- <br>
- <br>
-
- <h3>后端返回值 + 前端Ajax方式</h3>
- <div th:if="${fileNames} == null">没有文件可下载</div>
- <ul>
- <li th:each="fileName : ${fileNames}" th:text="${fileName} + ' 下载'"
- th:onclick="downloadFileByAjax([[${fileName}]])">
- </li>
- </ul>
- <br>
- <br>
-
- <h3>后端返回值 + 前端axios方式</h3>
- <div th:if="${fileNames} == null">没有文件可下载</div>
- <ul>
- <li th:each="fileName : ${fileNames}" th:text="${fileName} + ' 下载'"
- th:onclick="downloadFileByAxios([[${fileName}]])">
- </li>
- </ul>
- </body>
-
- </html>
SpringBoot实现文件上传和下载部分,到此结束了。我也是个新手,上面很多内容不够完善,甚至有些是错误的,请大家见谅。这是我在学习过程中做的笔记,感觉对大家可能有所帮助才发出来的,大家可以选择性查看。我也是在不断学习,不断完善自己。如果我在学习过程中,感觉对大家有用的部分,也会再次分享给大家的。谢谢!
上面有个问题还没有解决,也就是,前端怎么通过JQuery中的Ajax实现文件下载。这种方式和原生Ajax区别不大,下面就是代码,只需要设置返回类型为blob即可。(有时候,一个小问题,如果不熟悉,真的很难解决的。。。)
- $.ajax({
- type: "get",
- url: "/download/return",
- data: {
- fileName
- },
- xhrFields: { responseType: "blob" },
- success: function (response) {
- let blob = new Blob([response]);
- let elink = document.createElement('a');
- elink.download = fileName;
- elink.style.display = 'none';
- elink.href = URL.createObjectURL(blob);
- document.body.appendChild(elink);
- elink.click();
- // 释放URL 对象
- URL.revokeObjectURL(elink.href);
- document.body.removeChild(elink);
- }
- });