图像上传功能优化
优化之前的图片上传模块
控制层代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| public static final int MAX_AVATAR_SIZE = 10*1024*1024;
public static final List<String> AVATAR_TYPE = new ArrayList<>(); static { AVATAR_TYPE.add("image/jpeg"); AVATAR_TYPE.add("image/png"); AVATAR_TYPE.add("image/bmp"); AVATAR_TYPE.add("image/gif"); }
@RequestMapping("/alert_avatar") public JsonResult<String> alertAvatar(MultipartFile file,HttpSession session){ if(file==null){ System.out.println("============="); throw new FileEmptyException("文件为空异常"); } if(file.getSize()>MAX_AVATAR_SIZE){ throw new FileSizeException("文件超出大小限制"); } if(!AVATAR_TYPE.contains(file.getContentType())){ throw new FileTypeException("文件类型错误"); } String parent = session.getServletContext().getRealPath("upload"); File dir = new File(parent); if(!dir.exists()){ dir.mkdirs(); } String fileName = file.getOriginalFilename(); String[] splits = fileName.split("\\."); String suffix = splits[splits.length-1]; String uuid = UUID.randomUUID().toString().toUpperCase(); String newFileName = uuid+"."+suffix; System.out.println(newFileName); File dest = new File(dir,newFileName); try { file.transferTo(dest); } catch (IOException e) { throw new FileUploadIOException("文件读写错误"); }
Integer uid = getUidFromSession(session); System.out.println(dest.getPath()); String avatar = "/upload/"+newFileName; userService.alertAvatar(uid,avatar);
userService.alertAvatar(uid,avatar); return new JsonResult<>(OK,"用户头像修改成功",avatar); }
|
用户图像在数据库中存在的形式

获取根目录路径方式
1
| String parent = session.getServletContext().getRealPath("upload");
|
存在问题
通过上面方式获取的图像目录路径在SpringBoot
内嵌环境下拿到的是其内嵌Tomcat
的临时文件路径,每次启动项目,Tomcat
都会创建一个新的临时文件夹,从而导致当前登录无法获取历史上传图像路径
问题分析
SpringBoot
启动后,会将COMMON_DOC_ROOTS
设置成以下三个位置,如果这三个位置找不到,则会创建临时目录地址
1
| private static final String[] COMMON_DOC_ROOTS = { "src/main/webapp", "public","static" };
|
SpringBoot 内嵌 Tomcat创建的临时目录

解决方法一:手动指定存储路径
1.手动指定固定磁盘路劲去存储文件,不使用String parent = session.getServletContext().getRealPath("upload");
而使用固定路径String parent = "G:/upload/";
2.定制对应的配置类,配置Tomacat
虚拟目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package com.bang.store.configure;
import com.bang.store.interceptor.LoginInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList; import java.util.List;
@Configuration public class LoginInterceptorConfigure implements WebMvcConfigurer {
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**").addResourceLocations("file:G:/upload/"); } }
|
注意事项
addResourceLocations("file:G:/upload/")
里面的参数必须要写成"file:+路径"
的形式,该路径为你上传图片存储的位置
addResourceLocations("file:G:/upload/")
路径最后面的斜杠必须加
3.控制层代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| public static final int MAX_AVATAR_SIZE = 10*1024*1024;
public static final List<String> AVATAR_TYPE = new ArrayList<>(); static { AVATAR_TYPE.add("image/jpeg"); AVATAR_TYPE.add("image/png"); AVATAR_TYPE.add("image/bmp"); AVATAR_TYPE.add("image/gif"); }
@RequestMapping("/alert_avatar") public JsonResult<String> alertAvatar(MultipartFile file,HttpSession session){ if(file==null){ System.out.println("============="); throw new FileEmptyException("文件为空异常"); } if(file.getSize()>MAX_AVATAR_SIZE){ throw new FileSizeException("文件超出大小限制"); } if(!AVATAR_TYPE.contains(file.getContentType())){ throw new FileTypeException("文件类型错误"); } String parent = "G:/upload/"; File dir = new File(parent); if(!dir.exists()){ dir.mkdirs(); } String fileName = file.getOriginalFilename(); String[] splits = fileName.split("\\."); String suffix = splits[splits.length-1]; String uuid = UUID.randomUUID().toString().toUpperCase(); String newFileName = uuid+"."+suffix; System.out.println(newFileName); File dest = new File(dir,newFileName); try { file.transferTo(dest); } catch (IOException e) { throw new FileUploadIOException("文件读写错误"); }
Integer uid = getUidFromSession(session); System.out.println(dest.getPath()); String avatar = "/upload/"+newFileName; userService.alertAvatar(uid,avatar);
userService.alertAvatar(uid,avatar); return new JsonResult<>(OK,"用户头像修改成功",avatar); }
|
解决方法二:新建文件夹
在项目根目录下新建public
文件夹,这样在SpringBoot
项目启动时不会去创建临时文件夹

此时可以通过String parent = session.getServletContext().getRealPath("upload");
获取文件存取根路径
1.定制对应的配置类,配置Tomacat
虚拟目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package com.bang.store.configure;
import com.bang.store.interceptor.LoginInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList; import java.util.List;
@Configuration public class LoginInterceptorConfigure implements WebMvcConfigurer {
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**").addResourceLocations("file:G:/store/public/upload/"); } }
|
2.控制层代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| public static final int MAX_AVATAR_SIZE = 10*1024*1024;
public static final List<String> AVATAR_TYPE = new ArrayList<>(); static { AVATAR_TYPE.add("image/jpeg"); AVATAR_TYPE.add("image/png"); AVATAR_TYPE.add("image/bmp"); AVATAR_TYPE.add("image/gif"); }
@RequestMapping("/alert_avatar") public JsonResult<String> alertAvatar(MultipartFile file,HttpSession session){ if(file==null){ System.out.println("============="); throw new FileEmptyException("文件为空异常"); } if(file.getSize()>MAX_AVATAR_SIZE){ throw new FileSizeException("文件超出大小限制"); } if(!AVATAR_TYPE.contains(file.getContentType())){ throw new FileTypeException("文件类型错误"); } String parent = session.getServletContext().getRealPath("upload"); File dir = new File(parent); if(!dir.exists()){ dir.mkdirs(); } String fileName = file.getOriginalFilename(); String[] splits = fileName.split("\\."); String suffix = splits[splits.length-1]; String uuid = UUID.randomUUID().toString().toUpperCase(); String newFileName = uuid+"."+suffix; System.out.println(newFileName); File dest = new File(dir,newFileName); try { file.transferTo(dest); } catch (IOException e) { throw new FileUploadIOException("文件读写错误"); }
Integer uid = getUidFromSession(session); System.out.println(dest.getPath()); String avatar = "/upload/"+newFileName; userService.alertAvatar(uid,avatar);
userService.alertAvatar(uid,avatar); return new JsonResult<>(OK,"用户头像修改成功",avatar); }
|
参考资料
博客1
博客2
博客3
博客4