前 言
作为一名java程序员,或多或少都会使用到文件的上传和下载。
比如图片文件,excel文件等。所以,能快捷的实现对文件的上传和下载,或者有一个自己的模板,是一件很方便的事情。
今天就带领大家使用springboot来搭建文件的上传和下载的模板。其他不多说,直接上代码!!!
一、创建一个spring boot项目
1.1 开发工具 idea
1.2 jdk 1.8
1.3 具体项目搭建流程可以阅读我的另一篇博客(创建spring boot项目)
1.4 整体结构
二、搭建spring boot开发环境
2.1 添加pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.liyh</groupId> <artifactId>springboot_file_upload_download</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot_file_upload_download</name> <description>Demo project for Spring Boot</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.15</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.2 配置application.yml文件
# 配置端口
server:
port: 8085
# 去除thymeleaf的html严格校验
spring:
thymeleaf:
mode: LEGACYHTML5
# 取消模板文件缓存
cache: false
#设定thymeleaf文件路径 默认为src/main/resources/templates
freemarker:
template-loader-path: classpath:/templates
#设定静态文件路径,js,css等
mvc:
static-path-pattern: /static/**
servlet:
multipart:
# 设置单个文件大小
max-file-size: 200MB
# 设置单次请求文件的总大小
max-request-size: 200MB
2.3 编写摸板文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p>单文件上传</p> <form action="upload" method="POST" enctype="multipart/form-data"> 文件:<input type="file" name="file"/> <input type="submit"/> </form> <hr/> <p>文件下载</p> <a href="download">下载文件</a> <hr/> <p>多文件上传</p> <form method="POST" enctype="multipart/form-data" action="batch"> <p>文件1:<input type="file" name="file"/></p> <p>文件2:<input type="file" name="file"/></p> <p><input type="submit" value="上传"/></p> </form> </body> </html>
2.4 创建IndexController,FileController
package com.liyh.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * @Author: liyh * @Date: 2020/10/12 12:33 */ @Controller public class IndexController { @RequestMapping("/") public String index() { return "index"; } }
package com.liyh.controller; import com.liyh.utils.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.util.List; /** * @Author: liyh * @Date: 2020/10/12 11:58 */ @RestController public class FileController { private static final Logger log = LoggerFactory.getLogger(FileController.class); @RequestMapping(value = "/upload") public String upload(@RequestParam("file") MultipartFile file) { try { if (file.isEmpty()) { return "文件为空"; } // 获取大小 long size = file.getSize(); log.info("文件大小: " + size); // 判断上传文件大小 if (!FileUtils.checkFileSize(file,50,"M")) { log.error("上传文件规定小于50MB"); return "上传文件规定小于50MB"; } // 获取文件名 String fileName = file.getOriginalFilename(); log.info("上传的文件名为:" + fileName); // 获取文件的后缀名 String suffixName = fileName.substring(fileName.lastIndexOf(".")); log.info("文件的后缀名为:" + suffixName); // 设置文件存储路径 String filePath = "C:/software/file/"; String path = filePath + fileName; File dest = new File(path); // 检测是否存在目录 if (!dest.getParentFile().exists()) { dest.getParentFile().mkdirs();// 新建文件夹 } file.transferTo(dest);// 文件写入 return "上传成功"; } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return "上传失败"; } @PostMapping("/batch") public String handleFileUpload(HttpServletRequest request) { List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file"); MultipartFile file = null; BufferedOutputStream stream = null; for (int i = 0; i < files.size(); ++i) { file = files.get(i); String filePath = "C:/software/file/"; if (!file.isEmpty()) { try { byte[] bytes = file.getBytes(); stream = new BufferedOutputStream(new FileOutputStream( new File(filePath + file.getOriginalFilename())));//设置文件路径及名字 stream.write(bytes);// 写入 stream.close(); } catch (Exception e) { stream = null; return "第 " + i + " 个文件上传失败 ==> " + e.getMessage(); } } else { return "第 " + i + " 个文件上传失败因为文件为空"; } } return "上传成功"; } @GetMapping("/download") public String downloadFile(HttpServletRequest request, HttpServletResponse response) { String fileName = "timg.jpg";// 文件名 String result = FileUtils.downloadFiles(request, response, fileName); if (request == null) { return null; } return result; } }
2.4 判断文件大小的工具类FileUtils
package com.liyh.utils; import org.springframework.core.io.ClassPathResource; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; /** * @Author: liyh * @Date: 2020/11/4 16:10 */ public class FileUtils { /** * 下载文件 * @param request * @param response * @param fileName * @return * @throws IOException */ public static String downloadFiles(HttpServletRequest request, HttpServletResponse response, String fileName){ if (StringUtils.isEmpty(fileName)) { return "文件名称为空"; } //设置文件路径 ClassPathResource classPathResource = new ClassPathResource("templates/" + fileName); File file = null; try { file = classPathResource.getFile(); } catch (IOException e) { e.printStackTrace(); return "文件不存在"; } response.setHeader("content-type", "application/octet-stream"); // 设置强制下载不打开 response.setContentType("application/force-download"); // 设置文件名 response.addHeader("Content-Disposition", "attachment;fileName=" + fileName); byte[] buffer = new byte[1024]; InputStream fis = null; BufferedInputStream bis = null; try { fis = new FileInputStream(file); bis = new BufferedInputStream(fis); OutputStream os = response.getOutputStream(); int i = bis.read(buffer); while (i != -1) { os.write(buffer, 0, i); i = bis.read(buffer); } } catch (Exception e) { e.printStackTrace(); } finally { if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } return "文件下载成功"; } /** * 判断文件大小 * * @param file 文件 * @param size 限制大小 * @param unit 限制单位(B,K,M,G) * @return */ public static boolean checkFileSize(MultipartFile file, int size, String unit) { if (file.isEmpty() || StringUtils.isEmpty(size) || StringUtils.isEmpty(unit)) { return false; } long len = file.getSize(); double fileSize = 0; if ("B".equals(unit.toUpperCase())) { fileSize = (double) len; } else if ("K".equals(unit.toUpperCase())) { fileSize = (double) len / 1024; } else if ("M".equals(unit.toUpperCase())) { fileSize = (double) len / 1048576; } else if ("G".equals(unit.toUpperCase())) { fileSize = (double) len / 1073741824; } if (fileSize > size) { return false; } return true; } }
三、摸板文件
四、启动项目,进行测试
4.1 启动项目,访问结果:
4.2 测试单个文件上传
4.2.1 测试小于50MB的文件
测试结果(文件上传成功):
4.2.2 测试大于50MB的文件
测试结果(文件上传失败):
注意:在上传文件时,tomcat默认上传文件大小为1mb,当上传文件太大时会报错,要在application.yml配置上传文件大小,然后才FileController去判断文件大小,大于50MB上传失败!!!
4.3 测试文件下载
4.4 测试多个文件
测试结果(文件上传成功):