文件上传

简介:SpringBoot文件上传、UUID文件名上传及按日期目录分类上传。

  • 需求: 演示 Spring-Boot 通过表单注册用户,并支持上传图片
  • 需求: 演示 Spring-Boot 通过表单注册用户,并支持上传图片

1. 创建 templates/upload.html , 要求头像只能选择一个, 而potos可以上传多个图片

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>upload</title>
</head>
<body bgcolor="#CED3FE">
<img src="images/1.GIF"/>
<hr/>
<div style="text-align: center">
    <h1>注册用户~</h1>
    <form action="#" method="post" th:action="@{/upload}" enctype="multipart/form-data">
        用户名:<input type="text" style="width:150px" name="name"/><br/><br/>
        电 邮:<input type="text" style="width:150px" name="email"/><br/><br/>
        年 龄:<input type="text" style="width:150px" name="age"/><br/><br/>
        职 位:<input type="text" style="width:150px" name="job"/><br/><br/>
        头 像:<input type="file" style="width:150px" name="header"><br/><br/>
        宠 物:<input type="file" style="width:150px" name="photos" multiple><br/><br/>
        <input type="submit" value="注册"/>
        <input type="reset" value="重新填写"/>
    </form>
</div>
<hr/>
<img src="images/logo.png"/>
</body>
</html>

2. 创建 UploadController.java

package com.xjz.springboot.controller;

import com.xjz.springboot.Utils.WebUtils;
import lombok.extern.slf4j.Slf4j;
import org.omg.CORBA.INTERNAL;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
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 java.io.File;
import java.io.IOException;
import java.util.UUID;

@Slf4j
@Controller
public class UploadController {
    @GetMapping("/upload.html")
    public String uploadPage(){
        return "upload";
    }

    /**
     * MultipartFile 自动封装上传过来的文件
     * @return
     */
    @ResponseBody
    @PostMapping("/upload")
    public String upload(@RequestParam("name") String name,
                         @RequestParam("email")String email,
                         @RequestParam("age")Integer age,
                         @RequestParam("job")String job,
                         @RequestParam("header")MultipartFile header,
                         @RequestParam("photos")MultipartFile[] photos) throws IOException {
        log.info("上传的信息 name={}, email={}, age={}, job={}, header={},photo={}",
                name,email,age,job,header.getSize(),photos.length);

        //也可以自己动态的创建上传文件目录 , 来存放文件 , 比如在resources/static/images/upload/
        String path = ResourceUtils.getURL("classpath:").getPath();

        File file = new File(path + WebUtils.getUploadFileDirectory());
        if (!file.exists()) { //如果目录不存在,我们就创建,在 java io
            file.mkdirs();
        }

        if (!header.isEmpty()){ //处理头像
            //保存到文件服务器或OSS 服务器
            //需要先创建好 d://temp_upload
            String originalFilename = header.getOriginalFilename();
            String fileName = UUID.randomUUID().toString() + "_" + System.currentTimeMillis() + originalFilename;

            //方式1:指定某个目录存放上传文件
            //header.transferTo(new File("d://temp_upload//" + originalFilename));
            //方式2:动态的创建文件存放文件
            header.transferTo(new File(file.getAbsolutePath() + "/" + fileName));
            log.info("保存文件的绝对路径={}" + file.getAbsolutePath());
        }
        if (photos.length>0){
            for (MultipartFile photo : photos) {
                if (!photo.isEmpty()){
                    String originalFilename = photo.getOriginalFilename();
                    String fileName = UUID.randomUUID().toString() + "_" + System.currentTimeMillis() + originalFilename;
                    //photo.transferTo(new File("d:\\temp_upload\\" + originalFilename));
                    //保存到动态创建的目录
                    photo.transferTo(new File(file.getAbsolutePath() + "/" + fileName));
                }
            }
        }
        return "注册用户成功/文件上传成功";
    }
}

3. 修改WebCofig配置,放行/upload.html 和 /upload 请求

package com.xjz.springboot.webConfig;

import com.xjz.springboot.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 这里实现Spring-Boot 定制功能,加入自己的配置
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    //将我们的拦截器, 注入到容器中

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")  //拦截所有请求
                .excludePathPatterns("/","/login","/images","/upload.html","/upload");//放行的请求,可以根据需要添加
    }

    //原始方法添加拦截器--》bean容器
/*    @Bean
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                System.out.println("addInterceptors~~");
                //加入我们的拦截器
                registry.addInterceptor(new LoginInterceptor())
                        .addPathPatterns("/**")  //拦截所有请求
                        .excludePathPatterns("/","/login","/images");//放行的请求,可以根据需要添加
            }
        };
    }*/

}

4. 根据项目需求修改文件上传的参数,否则文件上传会抛出异常

springboot 上传 sftp springboot 上传文件带body_java

5. resources/application.yml文件配置

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 50MB

6. 运行结果

springboot 上传 sftp springboot 上传文件带body_学习_02

springboot 上传 sftp springboot 上传文件带body_学习_03

7. 扩展

1.解决文件覆盖问题, 如果文件名相同, 会出现覆盖问题, 如何解决

//在UploadControl.java 文件中 添加UUID随机文件名
String fileName = UUID.randomUUID().toString() + "_" + System.currentTimeMillis() + originalFilename;

springboot 上传 sftp springboot 上传文件带body_spring boot_04

  1. 解决文件分目录存放问题, 如果将文件都上传到一个目录下,当上传文件很多时,会造成访问文件速度变慢,因此 可以将文件上传到不同目录 比如 一天上传的文件,统一放到一个文件夹 年/月/日, 比如 2023/04/01 目录

WebUtils.java

package com.xjz.springboot.Utils;

import java.text.SimpleDateFormat;
import java.util.Date;

public class WebUtils {

    //定义一个文件上传的路径
    public static String UPLOAD_FILE_DIRECTORY = "static/images/upload/";

    //编写方法,生成一个目录-根据当前日期 年/月/日

    public static String getUploadFileDirectory() {
        //format的用法 是将当前时间格式转换为指定格式
        return UPLOAD_FILE_DIRECTORY + new SimpleDateFormat("yyyy/MM/dd").format(new Date());
    }
}

springboot 上传 sftp springboot 上传文件带body_学习_05

最后,祝大家愚人节快乐~