SpringBoot 上传文件到本地磁盘

  • Post author:
  • Post category:其他


参考资料:

1.

SpringMVC上传文件的 4 种方式,你都会么?| SpringMVC第6篇


2.https://blog.csdn.net/justry_deng/article/details/80972817/

3.

springboot实现本地存储文件上传及提供http访问服务

💧需求: 上传文件分别存到两个List中,两个List和json数据同时提交到后端

⏹前端HTML

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>文件上传</h1>
    文件上传1<input class="fileTest1" type="file">
    文件上传2<input class="fileTest1" type="file">
    文件上传3<input class="fileTest1" type="file">
    <hr>
    文件上传11<input class="fileTest2" type="file">
    文件上传22<input class="fileTest2" type="file">
    文件上传33<input class="fileTest2" type="file">

    <hr>
    <button id="btn">文件上传</button>
</body>
<script th:src="@{js/jquery.min.js}"></script>
<script>

    // 点击发送Ajax请求
    $('#btn').on('click', function () {

        // 构建一个FormData对象
        var formData = new FormData();

        // 获取上传的所有文件,并进行遍历
        $(".fileTest1").each(function () {
            // this代表上传的每一个文件
            const file1List = this.files[0];
            if (!!file1List) {
                formData.append("files1", file1List);
            }
        });
        // files1这个key中同时存储着文件和字符串
        formData.append("files1", "testString");

        $(".fileTest2").each(function () {
            // this代表上传的每一个文件
            const file2List = this.files[0];
            if (!!file2List) {
                formData.append("files2", file2List);
            }
        });

        // 将对象序列化为字符串传到后端
        // 要发送的参数
        const params1 = {
            name: 'wangwu',
            age: 30,
            card: ["abc", "bbc"]
        };
        formData.append("jsonData1", JSON.stringify(params1));
        formData.append("jsonData1", 1);
        formData.append("jsonData1", "测试信息");
        formData.append("jsonData1", ["名字", "年龄", "住址"]);

        const params2 = {
            name: 'zhaoliu',
            age: 20
        };
        formData.append("jsonData2", JSON.stringify(params2));
        $.ajax({
            // 请求地址
            url: '/wjec/groupFileUpload2',
            type: "post",
            // 因为我们要同时将json和文件数据同时提交到后端,所以需要使用FormData这个对象
            // 该对象可以同时存储json和文件二进制流数据
            data: formData,
            /*
            	jQuery的ajax()方法发送的数据默认是序列化后的字符串,因此processData的值默认为true
            	我们要同时传输文件和表单数据,所以将contentType设置为false,告诉jQuery不要将要发送的数据处理为字符串
			*/
            processData: false,
            // 告诉jQuery不要去设置Content-Type请求头
            // FormDate对象是XMLHttpRquest2的类型,利用XHR对象发送FormDate生成的数据时,可以直接发送,不需要设置头部,
            // XHR对象能够会自动识别数据类型是FormDate的实例,并配置相关的头部.
            contentType: false,
            // 请求成功以后函数被调用
            success: function (response) {
                // response为服务器端返回的数据,方法内部会自动将json字符串转换为json对象
                console.log(response);
            }
        })
    });
</script>
</html>



⏹后端接收方式1—原生方式接收

@PostMapping("/groupFileUpload")
@ResponseBody
public String groupFileUpload(MultipartFile[] files1, MultipartFile[] files2, String jsonData1, String jsonData2){

   System.out.println(jsonData1);
   System.out.println(jsonData2);

   List<MultipartFile> multipartFiles1 = Arrays.asList(files1);
   List<MultipartFile> multipartFiles2 = Arrays.asList(files2);

   return "groupFileUpload";
}



⏹后端接收方式2—MultipartHttpServletRequest接口接收

通过

MultipartHttpServletRequest

接口来处理文件上传

1、springmvc 接受到上传文件的的请求之后,会将请求转换为 MultipartHttpServletRequest 类型的对象

2、MultipartHttpServletRequest 中提供了一系列方法来获取请求中的所有参数信息

3、其中 getParameterMap()用来获取非文件类型的参数列表

4、getMultiFileMap()方法用来获取上传的文件列表

@PostMapping("/groupFileUpload1")
@ResponseBody
public String groupFileUpload1(MultipartHttpServletRequest request){

    Map<String, String[]> parameterMap = request.getParameterMap();
    // 前端放到jsonData1key中的value会以数组的方式进行存储
    String[] params = parameterMap.get("jsonData1");
    System.out.println(Arrays.toString(params));
    String[] params2 = parameterMap.get("jsonData2");
    System.out.println(Arrays.toString(params2));
    // 在书写js的时候,files1同时存储着文件和json信息,通过这种方式可以将json信息获取出来
    String[] files1 = parameterMap.get("files1");
    System.out.println(Arrays.toString(files1));
    
    // 获取前端传入后端的文件
    MultiValueMap<String, MultipartFile> multiFileMap = request.getMultiFileMap();
    List<MultipartFile> multipartFiles1 = multiFileMap.get("files1");
    List<MultipartFile> multipartFiles2 = multiFileMap.get("files2");

    return "groupFileUpload";
}



⏹后端接收方式3—自定义实体类接收


自定义一个实体类

import org.springframework.web.multipart.MultipartFile;
import java.util.List;

public class FileUploadEntity {

    private String[] jsonData1;
    private String[] jsonData2;
    private List<MultipartFile> files1;
    private List<MultipartFile> files2;
    // ...省略get和set方法
}


通过实体类的方式接收

@PostMapping("/groupFileUpload2")
@ResponseBody
public String groupFileUpload2(FileUploadEntity entity){

    String[] jsonData1 = entity.getJsonData1();
    System.out.println(Arrays.toString(jsonData1));

    String[] jsonData2 = entity.getJsonData2();
    System.out.println(Arrays.toString(jsonData2));

    List<MultipartFile> files1 = entity.getFiles1();
    List<MultipartFile> files2 = entity.getFiles2();

    return "groupFileUpload";
}



⏹SpringBoot接收文件保存到本地磁盘

配置文件

# 端口号设置
server.port: 8082

# 应用程序的上下文设置
server.servlet.context-path: /wjec

#上传文件的最大限制
spring.servlet.multipart.max-file-size = 300MB
spring.servlet.multipart.max-request-size = 900MB

# 关闭模板的缓存,默认是开启的
spring.thymeleaf.cache=false

# 自定义保存文件的位置
web.upload-path: D:/data/

#除了带上Spring Boot默认的静态资源路径之外,加上file:${web.upload-path}指向外部的文件资源上传路径。该路径下的静态资源可以直接对外提供HTTP访问服务。
#spring.resources.static-locations的方式已经过时,现在需要通过下面的配置方式指定
spring.web.resources.static-locations= classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${web.upload-path}

后端处理

import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.util.UriComponentsBuilder;

@Controller
public class FileUploadController {

    // 绑定文件上传路径到uploadPath
    @Value("${web.upload-path}")
    private String uploadPath;
    
	// 注入上下文对象的url
    @Value("${server.servlet.context-path}")
    private String contextPath;
	
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
    
    @PostMapping("/groupFileUpload1")
    @ResponseBody
    public String groupFileUpload1(MultipartHttpServletRequest request){
		
		// 通过日期对上传的文件归类保存
        String format = sdf.format(new Date());
        File folder = new File(uploadPath + format);
        if (!folder.isDirectory()) {
            folder.mkdirs();
        }
		
		// 获取前端上传的文件
		MultiValueMap<String, MultipartFile> multiFileMap = request.getMultiFileMap();
		
		// 存储静态资源访问url的List
        ArrayList<String> urlList = new ArrayList<>();
        // 获取files1为key的上传文件列表
        List<MultipartFile> multipartFiles1 = multiFileMap.get("files1");
        try {
            for (MultipartFile multipartFile: multipartFiles1){
                // 对上传的文件重命名,避免文件重名
                String oldName = multipartFile.getOriginalFilename();
                String newName = UUID.randomUUID().toString()
                        + oldName.substring(oldName.lastIndexOf("."), oldName.length());

                // 文件保存
                multipartFile.transferTo(new File(folder, newName));
				
				// 通过工具类构造静态资源访问url
                UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance();
                uriComponentsBuilder
                        .scheme(request.getScheme())
                        .host(request.getServerName())
                        .port(request.getServerPort())
                        .path(contextPath + "/")
                        .path(format + newName)
                        .build();

                urlList.add(uriComponentsBuilder.toUriString());
            }
        } catch (IOException e) {
            System.out.println(e);
        }
		
		// 打印存储到本地磁盘资源的访问url
        System.out.println(urlList.toString());

        return "";
    }
}



版权声明:本文为feyehong原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。