SpringBoot上传文件
文件上传 是程序开发过程中使用到的一个功能
- 添加商品 用户头像 文章封面
- 富文本编辑器 (插件文件上传)
文件上传原理
- Javaweb中 文件上传 用IO流 定义一个 type 将其设置成为一个 文件上传流的类型 就可以实现文件上传的操作 从请求中 读取对应的请求流 最后将文件写入到服务器中
实现文件上传 本质上是实现 共享资源 把用户的自己的电脑中的文件 通过程序上传到服务器上的过程 称为 文件上传
临时目录
- 先将文件内容复制在 临时目录中 然后再将内容复制到服务器磁盘
- 原因 文件上传不会直接 上传到真实的目录中 需要经过一个 临时目录的中转 防止
- 出现网络的断开 或者用户上传直接刷新 或者直接取消 如果因为因为这些原因 就会造成大量的垃圾文件
- 保证真实目录上传的文件一定是有效的
整体流程就是 将文件通过java io流复制到服务器
使用Springboot实现文件上传
本地上传
构建一个Springboot工程
准备一个页面文件上传
- 在resources/upload 建立一个文件存储对应 所上传的文件 实现后台的文件上传
- 指定文件的上传目录 配置Springboot静态资源存储服务,将上传的文件放入指定的目录中
通过http请求服务资源
- 对文件上传的思考优化和控制 文件的格式 文件的大小 文件的重命名 文件的目录分类
request.getParameter(“dir”); 一种取参数方式,把jsp文件中的数据读取出来 然后封装利用起来,
在javaweb中 文件上传
HttpServletRequest request = null;
// 当前tomcat目录下
String servrepath = request.getServletContext().getContextPath();
在Springboot中 识别该类型的目录 解决方案
Springboot去指定任何目录作为资源的访问目录
Springboot 有一个目录 static 就是一个资源目录 这个目录中的文件 是可以通过 http直接访问的
Springboot 提供一个静态资源目录的额外的映射机制 就是静态资源服务映射 类似于 nginx的静态资源映射
资源映射 核心代码分析
前面必须有这个file
Registry.addResourceHandler(“访问路径”).addResourceLocations(“file:上传资源的路径”);
Controller
@Api(tags = "图片上传")
@RestController
@CrossOrigin //前后端分离配置跨域访问
@RequestMapping("/upload")
public class UploadController {
@Autowired
private UploadService uploadService;
// 异步上传
@PostMapping("/file")
@ApiOperation("文件上传")
@ResponseBody
public String upload(@RequestParam("file") MultipartFile multipartFile , HttpServletRequest request){
if(multipartFile.isEmpty()){
return "文件为空";
}
long size= multipartFile.getSize();
// 获取上传文件的原始名字
String filename = multipartFile.getOriginalFilename();
String contentType = multipartFile.getContentType();
// 获取用户指定的文件夹
// 这个文件为什么用才页面传过来
// 做隔离 不同业务 不同文件放在不同的目录中
String dir = request.getParameter("dir"); // 在前端输入的存储位置
return uploadService.uploadImg(multipartFile,dir);
}
}
Service
@Service
public class UploadService {
@Value("${file.uploadFolder}")
private String uploadFolder;
// MultipartFile 这个对象是SpringMvc提供的文件上传的请求的类
// 它的底层会自动和httpServletRequest request 中的request.getInputStream() 整合 从而达到文件上传的目的
// dir 指定上传的目录
// 文件上传底层的原理是 request.getInputStream()
public String uploadImg(MultipartFile file ,String dir ){
try {
// 截取文件名 的后缀 防止出现文件名的重复 覆盖
String realfilename = file.getOriginalFilename();
String imgSuffix = realfilename.substring(realfilename.lastIndexOf("."));
// 将其生成唯一的文件名
String newfilename = UUID.randomUUID().toString()+imgSuffix;
// 日期目录
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
String datePath = dateFormat.format(new Date());
String servrepath=uploadFolder;
// 指定文件上传的目录 生成一个最终的目录
File targetFile = new File(servrepath+dir,datePath);
if(!targetFile.exists()) targetFile.mkdir();
// 指定文件上传以后服务器完整的文件名
File targetFilname = new File(targetFile,newfilename);
// 文件上传
file.transferTo(targetFilname);
String filename = dir+"/"+datePath+"/"+newfilename;
return filename;
} catch (IOException e) {
e.printStackTrace();
return "fail";
}
}
}
WebMvcConfiguration
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Value("${file.staticPatternPath}")
private String staticPatternPath;
@Value("${file.uploadFolder}")
private String uploadFolder;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(staticPatternPath).addResourceLocations("file:"+uploadFolder);
}
}
dev.yml
# 本机配置
file:
staticPatternPath: /images/**
uploadFolder: F:/temp/
prod.yml
#服务器配置
file:
staticPatternPath: /images/**
uploadFolder: www/home/
appplication.yml
servlet:
multipart:
# 默认是打开的
enabled: true
#进行 环境隔离
profiles:
active: prod
# 单个文件的小大 默认是1MB
max-file-size: 50MB
# 设置总上传的数据大小
max-request-size: 500MB
# 设置临时目录
# location: "临时目录的位置使用//"