springboot注解有哪些 SpringBoot实现文件上传①

在web开发中,文件上传是必不可少的一部分 。比如头像上传,添加商品、上传图片等等需求......就是把文件上传保存到服务器的过程 。前言:在web开发中,文件上传是必不可少的一部分 。比如头像上传,添加商品、上传图片等等需求......就是把文件上传保存到服务器的过程 。
单文件上传实现步骤01、搭建项目搭建一个SpringBoot项目
<?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.6.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.qd</groupId><artifactId>uploadDemo</artifactId><version>0.0.1-SNAPSHOT</version><name>uploadDemo</name><description>文件上传demo</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>server:port: 8082 # 应用端口spring:# freemarkerfreemarker:suffix: .htmlcache: false# 文件上传配置servlet:multipart:# 是否开启http上传处理enabled: true# 单个文件最大长度max-file-size: 2MB# 最大请求文件的大小max-request-size: 10MB# 设置临时目录# location: F://data//temp02、准备文件上传页面在resources/templates/新增upload.html页面
package com.qd.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;/** * Create by IntelliJ IDEA * * @Author: qiandu * @Blog: https://www.cnblogs.com/qd666 * @Date: 2021/11/21 21:01 */@Controllerpublic class UploadController {@GetMapping("/upload")public String toUpload() {return "upload";}}03、后台实现UploadService
package com.qd.service;import org.springframework.stereotype.Service;import org.springframework.web.multipart.MultipartFile;import java.io.File;import java.io.IOException;/** * 文件上传 * * @Author: qiandu * @Blog: https://www.cnblogs.com/qd666 * @Date: 2021/11/21 21:20 */@Servicepublic class UploadService {/*** MultipartFile 对象是springMVC提供的文件上传接收的类* 文件上传底层原理 request.getInpuStream()** @param multipartFile* @param dir* @return*/public String uploadImg(MultipartFile multipartFile, String dir) {// 1:指定文件上传的目录File targetFile = new File("D:\\tmp\\" + dir);try {// 2:如果targetFile不存在,则创建if (!targetFile.exists()) targetFile.mkdirs();// 3: 指定文件上传后的目录File targetFileName = new File(targetFile, "1.png"); // 先写死// 4:文件上传到指定的目录multipartFile.transferTo(targetFileName);return "ok";} catch (IOException e) {e.printStackTrace();return "fail";}}}UploadController
package com.qd.controller;import com.qd.service.UploadService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;/** * Create by IntelliJ IDEA * * @Author: qiandu * @Blog: https://www.cnblogs.com/qd666 * @Date: 2021/11/21 21:01 */@Controllerpublic class UploadController {@Autowiredprivate UploadService uploadService;@GetMapping("/upload")public String toUpload() {return "upload";}@PostMapping("/upload/file")@ResponseBodypublic String upload(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) {// 1:空判断if (multipartFile.isEmpty()) {return "文件为空!!!";}multipartFile.getSize();//得到大小multipartFile.getOriginalFilename();//得到文件名String contentType = multipartFile.getContentType();//得到文件类型// 2:判断文件是否符合if (!"image/png".equals(contentType) || !"image/jpg".equals(contentType)) {return "文件格式不符合";}// 3:获取用户指定的文件夹// 目的:作隔离,不同业务、不同文件放入到不同的目录中String dir = request.getParameter("dir");return uploadService.uploadImg(multipartFile, dir);}}web页面
<h2>文件上传</h2><form action="/upload/file" method="post" enctype="multipart/form-data"><input type="text" name="dir" value="https://tazarkount.com/read/avatar" hidden><input type="file" name="file" accept="image/png,image/jpg"><input type="submit" value="https://tazarkount.com/read/点我上传"></form>结果

springboot注解有哪些 SpringBoot实现文件上传①

文章插图
04、后台改进上面的还有问题的,比如上传后的文件名称被写死,目录页应该按照年月日层级划分
【springboot注解有哪些 SpringBoot实现文件上传①】package com.qd.service;import org.springframework.stereotype.Service;import org.springframework.web.multipart.MultipartFile;import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.UUID;/** * 文件上传 * * @Author: qiandu * @Blog: https://www.cnblogs.com/qd666 * @Date: 2021/11/21 21:20 */@Servicepublic class UploadService {/*** MultipartFile 对象是springMVC提供的文件上传接收的类* 文件上传底层原理 request.getInpuStream()** @param multipartFile* @param dir* @return*/public String uploadImg(MultipartFile multipartFile, String dir) {try {// 1:真实的文件名称String originalFilename = multipartFile.getOriginalFilename(); // 上传的文件aa.jpg// 2:截取后的文件名称 .jpgString imgSuffix = originalFilename.substring(originalFilename.lastIndexOf(".")); // 得到.jpg// 3:生成唯一的文件名称String newFileName = UUID.randomUUID().toString() + imgSuffix;// 随机生成如:dfasf42432.jpg// 4:日期作为目录隔离文件SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");String datePath = dateFormat.format(new Date()); // 日期目录:2021/11/21// 5:最终文件的上传目录File targetFile = new File("D:\\tmp\\" + dir, datePath); // 生成的最终目录; D://tmp/avatar/2021/11/21// 6:如果dirFile不存在,则创建if (!targetFile.exists()) targetFile.mkdirs();// 7: 指定文件上传后完整的文件名File dirFileName = new File(targetFile, newFileName); // 文件在服务器的最终路径是:D://tmp/avatar/2021/11/21/dfasf42432.jpg// 8:文件上传multipartFile.transferTo(dirFileName);return "ok";} catch (IOException e) {e.printStackTrace();return "fail";}}}结果

springboot注解有哪些 SpringBoot实现文件上传①

文章插图
05、前台改进目前,前端需要先选择上传的图片,然后需要点击上传按钮,方能上传 。那能不能改进才只要选中图片即可自动上传呢?
<h2>文件上传</h2><form action="/upload/file" id="uploadform" method="post" enctype="multipart/form-data"><input type="text" name="dir" value="https://tazarkount.com/read/avatar" hidden><input type="file" name="file" accept="image/png,image/jpg" onchange="upload()"><!--<input type="submit" value="https://tazarkount.com/read/点我上传">--></form><script>function upload() {console.log("选择图片即可上传~")document.getElementById("uploadform").submit();}</script>ok~到这里本地的单文件上传就学习的差不多了,随之我们又遇到了另外一个问题:怎么获取上传的图片呢? 那么接下来将解决这个问题 。
获取文件文件可访问路径:http://localhost:8082/avatar/2021/11/21/dfasf42432.jpg
// 9:可访问的路径 http://localhost:8082/avatar/2021/11/21/dfasf42432.jpg String fileName = dir + "/" + datePath + "/" + newFileName; return fileName;
springboot注解有哪些 SpringBoot实现文件上传①

文章插图

但是此时仍然无法访问,怎么解决呢?———上传至服务器目录即当前tomcat服务器下webapps/目录
SpringBoot如何指定任意目录为资源的访问目录呢?
我们知道SpringBoot有一个目录static 在这个目录下的文件可以是直接通过http请求访问到的,但是程序会被打成jar包,文件无法写入,所以SpringBoot提供一个资源目录映射的机制 。接下来我们尝试一下 。
01、新建配置类package com.qd.config;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/** * 静态资源映射配置类 * * @Author: qiandu * @Blog: https://www.cnblogs.com/qd666 * @Date: 2021/11/22 5:50 */@Configurationpublic class WebMvcConfiguration implements WebMvcConfigurer {// 配置文件上传的额外的静态资源配置@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {//registry.addResourceHandler("/资源的访问路径").addResourceLocations("映射目录");registry.addResourceHandler("/uploadImg/**").addResourceLocations("file:D://tmp//");}}分析:如果你将文件上传到了D://tmp目录 可以通过http://localhost:8082/uploadImg/aa.jpg访问 。访问测试

springboot注解有哪些 SpringBoot实现文件上传①

文章插图

ok,到了这一步还是有问题的,在前面我们将 addResourceLocations("file:D://tmp//")写死了,细想一下,它如果是linux系统呢?是不是还要继续改进 。
02、改进WebMvcConfiguration 配置类改进
package com.qd.config;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/** * 静态资源映射配置类 * * @Author: qiandu * @Blog: https://www.cnblogs.com/qd666 * @Date: 2021/11/22 5:50 */@Configurationpublic class WebMvcConfiguration implements WebMvcConfigurer {@Value("${file.staticPatterPath}")private String staticPatterPath;@Value("${file.uploadFolder}")private String uploadFolder;// 配置文件上传的额外的静态资源配置@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {//registry.addResourceHandler("/资源的访问路径").addResourceLocations("映射目录");registry.addResourceHandler(staticPatterPath + "**").addResourceLocations("file:" + uploadFolder);}}新建yml文件作环境隔离
# 本机配置file:rootPath: http://localhost:8082staticPatterPath: /uploadImg/uploadFolder: D:/tmp/# 服务器配置file:rootPath: https://www.xxx.comstaticPatterPath: /uploadImg/uploadFolder: /www/upload/改进service
package com.qd.service;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import org.springframework.web.multipart.MultipartFile;import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.UUID;/** * 文件上传 * * @Author: qiandu * @Blog: https://www.cnblogs.com/qd666 * @Date: 2021/11/21 21:20 */@Servicepublic class UploadService {// 根路径@Value("${file.rootPath}")private String rootPath;// 映射目录@Value("${file.uploadFolder}")private String uploadFolder;// 资源的访问路径@Value("${file.staticPatterPath}")private String staticPatterPath;/*** MultipartFile 对象是springMVC提供的文件上传接收的类* 文件上传底层原理 request.getInpuStream()** @param multipartFile* @param dir* @return*/public String uploadImg(MultipartFile multipartFile, String dir) {try {// 1:真实的文件名称String originalFilename = multipartFile.getOriginalFilename(); // 上传的文件aa.jpg// 2:截取后的文件名称 .jpgString imgSuffix = originalFilename.substring(originalFilename.lastIndexOf(".")); // 得到.jpg// 3:生成唯一的文件名称String newFileName = UUID.randomUUID().toString() + imgSuffix;// 随机生成如:dfasf42432.jpg// 4:日期作为目录隔离文件SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");String datePath = dateFormat.format(new Date()); // 日期目录:2021/11/21// 5:最终文件的上传目录File targetFile = new File(uploadFolder + dir, datePath); // 生成的最终目录; D://tmp/avatar/2021/11/21// 6:如果dirFile不存在,则创建if (!targetFile.exists()) targetFile.mkdirs();// 7: 指定文件上传后完整的文件名File dirFileName = new File(targetFile, newFileName); // 文件在服务器的最终路径是:D://tmp/avatar/2021/11/21/dfasf42432.jpg// 8:文件上传multipartFile.transferTo(dirFileName);// 9:可访问的路径 http://localhost:8082/avatar/2021/11/21/dfasf42432.jpgString fileName = dir + "/" + datePath + "/" + newFileName;return rootPath +staticPatterPath+ fileName;} catch (IOException e) {e.printStackTrace();return "fail";}}}03、获取文件多个信息返回map即可
UploadService
package com.qd.service;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import org.springframework.web.multipart.MultipartFile;import java.io.File;import java.io.IOException;import java.io.StringReader;import java.text.SimpleDateFormat;import java.util.*;/** * 文件上传 * * @Author: qiandu * @Blog: https://www.cnblogs.com/qd666 * @Date: 2021/11/21 21:20 */@Servicepublic class UploadService {// 根路径@Value("${file.rootPath}")private String rootPath;// 映射目录@Value("${file.uploadFolder}")private String uploadFolder;// 资源的访问路径@Value("${file.staticPatterPath}")private String staticPatterPath;/*** MultipartFile 对象是springMVC提供的文件上传接收的类* 文件上传底层原理 request.getInpuStream()** @param multipartFile* @param dir* @return*/public Map<String, Object> uploadImgMap(MultipartFile multipartFile, String dir) {try {// 1:真实的文件名称String originalFilename = multipartFile.getOriginalFilename(); // 上传的文件aa.jpg// 2:截取后的文件名称 .jpgString imgSuffix = originalFilename.substring(originalFilename.lastIndexOf(".")); // 得到.jpg// 3:生成唯一的文件名称String newFileName = UUID.randomUUID().toString() + imgSuffix;// 随机生成如:dfasf42432.jpg// 4:日期作为目录隔离文件SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");String datePath = dateFormat.format(new Date()); // 日期目录:2021/11/21// 5:最终文件的上传目录File targetFile = new File(uploadFolder + dir, datePath); // 生成的最终目录; D://tmp/avatar/2021/11/21// 6:如果dirFile不存在,则创建if (!targetFile.exists()) targetFile.mkdirs();// 7: 指定文件上传后完整的文件名File dirFileName = new File(targetFile, newFileName); // 文件在服务器的最终路径是:D://tmp/avatar/2021/11/21/dfasf42432.jpg// 8:文件上传multipartFile.transferTo(dirFileName);// 9:可访问的路径 http://localhost:8082/avatar/2021/11/21/dfasf42432.jpgString fileName = dir + "/" + datePath + "/" + newFileName;Map<String, Object> map = new HashMap<>();map.put("url", rootPath + staticPatterPath + fileName); // urlmap.put("size", multipartFile.getSize());// 大小map.put("fileName", originalFilename);// 真实文件名称map.put("ext", imgSuffix);// 后缀名return map;} catch (IOException e) {e.printStackTrace();return null;}}}UploadController
package com.qd.controller;import com.qd.service.UploadService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;import java.util.Map;/** * Create by IntelliJ IDEA * * @Author: qiandu * @Blog: https://www.cnblogs.com/qd666 * @Date: 2021/11/21 21:01 */@Controllerpublic class UploadController {@Autowiredprivate UploadService uploadService;@GetMapping("/upload")public String toUpload() {return "upload";}@PostMapping("/upload/file2")@ResponseBodypublic Map<String, Object> uploadMap(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) {// 1:空判断if (multipartFile.isEmpty()) {return null;}// 2:判断文件是否符合//String contentType = multipartFile.getContentType();//得到文件类型//if (!"image/png".equals(contentType) || !"image/jpg".equals(contentType)) {//return "文件格式不符合";//}// 3:获取用户指定的文件夹// 目的:作隔离,不同业务、不同文件放入到不同的目录中String dir = request.getParameter("dir");return uploadService.uploadImgMap(multipartFile, dir);}}前端
<h2>文件上传</h2><form action="/upload/file2" id="uploadform" method="post" enctype="multipart/form-data"><input type="text" name="dir" value="https://tazarkount.com/read/avatar" hidden><input type="file" name="file" accept="image/png,image/jpg" onchange="upload()"><!--<input type="submit" value="https://tazarkount.com/read/点我上传">--></form><script>function upload() {console.log("选择图片即可上传~")document.getElementById("uploadform").submit();}</script>结果

springboot注解有哪些 SpringBoot实现文件上传①

文章插图
多文件上传方法一01、controller层多文件上传接口方法/*** 多文件按上传** @param multipartFiles* @param request* @return*/@PostMapping("/upload/batchUpload")@ResponseBodypublic List<Map<String, Object>> batchUpload(@RequestParam("file") MultipartFile[] multipartFiles, HttpServletRequest request) {if (multipartFiles.length < 0) {return new ArrayList<>();}// 获取用户指定的文件夹,业务隔离String dir = request.getParameter("dir");return uploadService.batchUpload(multipartFiles, dir);}tips:multipartFiles定义成数组,即可接收多文件
02、service层多文件上传方法/*** 多文件上传** @param multipartFiles* @return*/public List<Map<String, Object>> batchUpload(MultipartFile[] multipartFiles, String dir) {ArrayList<Map<String, Object>> list = new ArrayList<>();try {// 1:遍历获取每个上传的文件for (int i = 0; i < multipartFiles.length; i++) {MultipartFile multipartFile = multipartFiles[i];// 2:获取文件名String originalFilename = multipartFile.getOriginalFilename();// 3:取文件名后缀String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));// 4:文件重命名String newFileName = UUID.randomUUID().toString() + suffix;// 5:日期目录SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");String datePath = simpleDateFormat.format(new Date());// 6:上传目录File targetFile = new File(uploadFolder + dir, datePath);// 7:如果目录不存在,递归创建if (!targetFile.exists()) targetFile.mkdirs();// 8:文件上传目录File dirFileName = new File(targetFile, newFileName);// 9:文件上传multipartFile.transferTo(dirFileName);// 10:路径拼接String fileUrl = dir + "/" + datePath + "/" + newFileName;// 11:完整访问路径String linkUrl = rootPath + staticPatterPath + fileUrl;Map<String, Object> map = new HashMap<>();map.put("url", linkUrl); // urlmap.put("size", multipartFile.getSize());// 大小map.put("fileName", originalFilename);// 真实文件名称map.put("ext", suffix);// 后缀名list.add(map);}return list;} catch (IOException e) {e.printStackTrace();return new ArrayList<>();}}03、前端页面<h2>文件上传</h2><form action="/upload/batchUpload" id="uploadform" method="post" enctype="multipart/form-data"><input type="text" name="dir" value="https://tazarkount.com/read/avatar" hidden><input type="file" name="file" multiple accept="image/png,image/jpg" onchange="upload()"><!--<input type="submit" value="https://tazarkount.com/read/点我上传">--></form><script>function upload() {console.log("选择图片即可上传~")document.getElementById("uploadform").submit();}</script>测试结果

springboot注解有哪些 SpringBoot实现文件上传①

文章插图
方法二01、controller层多文件上传接口方法 /*** 多文件按上传** @param request* @return*/@PostMapping("/upload/batchUpload2")@ResponseBodypublic List<Map<String, Object>> batchUpload2(HttpServletRequest request) {// 1:得到 MultipartHttpServletRequest// MultipartHttpServletRequest接口简单地扩展了默认的HttpServletRequest接口,并提供一些用来处理请求文件的方法 。MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;// 2:获取上传文件列表,字段file由前台表单指定List<MultipartFile> fileList = multipartHttpServletRequest.getFiles("file");// 3:判断文件是否为空if (fileList.size() == 0) {return new ArrayList<>();}// 4:获取用户指定的文件夹,业务隔离String dir = request.getParameter("dir");return uploadService.batchUpload2(fileList, dir);}02、service层多文件上传方法 /*** 多文件上传** @param multipartFiles* @param dir* @return*/public List<Map<String, Object>> batchUpload2(List<MultipartFile> multipartFiles, String dir) {// 1:存放所有文件信息ArrayList<Map<String, Object>> list = new ArrayList<>();for (MultipartFile multipartFile : multipartFiles) {try {// 2:获取文件名String originalFilename = multipartFile.getOriginalFilename();// 3:取文件名后缀String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));// 4:文件重命名String newFileName = UUID.randomUUID().toString() + suffix;// 5:日期目录SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");String datePath = simpleDateFormat.format(new Date());// 6:上传目录File targetFile = new File(uploadFolder + dir, datePath);// 7:如果目录不存在,递归创建if (!targetFile.exists()) targetFile.mkdirs();// 8:文件上传目录File dirFileName = new File(targetFile, newFileName);// 9:文件上传multipartFile.transferTo(dirFileName);// 10:路径拼接String fileUrl = dir + "/" + datePath + "/" + newFileName;// 11:完整访问路径String linkUrl = rootPath + staticPatterPath + fileUrl;Map<String, Object> map = new HashMap<>();map.put("url", linkUrl); // urlmap.put("size", multipartFile.getSize());// 大小map.put("fileName", originalFilename);// 真实文件名称map.put("ext", suffix);// 后缀名list.add(map);} catch (Exception e) {e.printStackTrace();}}return list;}测试结果也是没毛病的~推荐第一种写法
示例代码:https://chenyu6666.lanzoui.com/inY8Owtnngd
ok~至此,关于本机的文件上传就探讨到此,后续我们将使用阿里云oss存储继续学习文件上传 。