Spring boot文件上传

目录

1.准备工作

1.创建Springboot项目添加web依赖

2.创建upload.html页面

2.单文件上传

创建文件上传接口

​编辑 单文件上传优化

3.多文件上传

4.整合为工具类


1.准备工作

1.创建Springboot项目添加web依赖

        
            org.springframework.boot
            spring-boot-starter-web
        

2.创建upload.html页面



    
        
        Title
    
    

        

上传单个文件到服务器路径下

上传单个文件

上传多个文件

enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。

默认地,表单数据会编码为 “application/x-www-form-urlencoded”。就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 “+” 加号,特殊符号转换为 ASCII HEX 值) 

描述
application/x-www-form-urlencoded 在发送前编码所有字符(默认)
multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
text/plain 空格转换为 “+” 加号,但不对特殊字符编码。

2.单文件上传

创建文件上传接口

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FileUploadController {

    //以时间作为文件夹
    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");

    @PostMapping("/uploadServerFile")
    public String uploadServerFile(MultipartFile uploadFile, HttpServletRequest req) {
        if ("".equals(uploadFile.getOriginalFilename())){
            return "";
        }
        //文件存在的物理路径,但会随着项目的重新启动而改变
        String realPath =
                req.getSession().getServletContext().getRealPath("/uploadFile/");
        System.out.println(realPath);
        String format = sdf.format(new Date());
        File folder = new File(realPath + format);
        String filePath="";
        if (!folder.isDirectory()) {
            folder.mkdirs();
        }
        //当前文件名
        String oldName = uploadFile.getOriginalFilename();
        //新文件名
        String newName = UUID.randomUUID().toString() +
                oldName.substring(oldName.lastIndexOf("."), oldName.length());
        try {
            //将接收到的文件传输到给定的目标文件。
            uploadFile.transferTo(new File(folder, newName));
            //项目访问文件的路径
            filePath = req.getScheme() + "://" + req.getServerName() + ":" +
                    req.getServerPort() + "/uploadFile/" + format + newName;

        } catch (IOException e) {
            e.printStackTrace();
            return "上传失败! ";
        }
        return filePath;
    }
}

其对应html的第一个表单,然后上传文件测试。

Spring boot文件上传_第1张图片

选择文件后点击上传按钮,显示如下,返回的路径可以通过通过浏览器访问。

Spring boot文件上传_第2张图片 单文件上传优化

但是这样做是有问题,上传图片到服务器根路径下的文件夹里,若重启服务器,图片则无法访问,这是因为每次重启服务器之后,都会在系统临时文件夹内,创建一个新的服务器,图片就保存在这里,若重启,又会产生一个新的服务器,此时访问的就是新服务器的图片资源,而图片根本就不在新服务器内。

  • windows的临时文件夹位置:

C:\Users\User\AppData\Local\Temp

开始修改

设置的图片保存路径的末尾必须有 /,代码中默认保存路径最后已经带有/

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FileUploadController {

    //以时间作为文件夹
    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");

    //文件存放的路径
    public static String fileSavePath="E:/uploadFile/";


    @PostMapping("/uploadPahtFile")
    public String uploadPahtFile(MultipartFile uploadFile, HttpServletRequest req) {
        if ("".equals(uploadFile.getOriginalFilename())){
            return "";
        }
        String filePath = "";
        String format = sdf.format(new Date());
        //固定物理路径
        File folder = new File(fileSavePath + format);
        //如果文件夹不存在则创建
        if (!folder.isDirectory()) {
            folder.mkdirs();//创建文件夹
        }
        //上传的文件名
        String oldName = uploadFile.getOriginalFilename();
        //新的文件名
        String newName = UUID.randomUUID().toString() +
                oldName.substring(oldName.lastIndexOf("."), oldName.length());
        try {
            //将uploadFile存到一个路径为:folder,名字为:newName的文件,
            uploadFile.transferTo(new File(folder, newName));
            //获取项目访问的路径
            filePath = req.getScheme() + "://" + req.getServerName() + ":" +
                    req.getServerPort() + "/uploadFile/" + format + newName;
        } catch (IOException e) {
            e.printStackTrace();
            return "上传失败! ";
        }
        return filePath;
    }
}

其对应html的第二个form,选择这种方式时需要对静态资源进行映射

 添加配置类,配置资源映射

import com.li.utils.FileUploadUtil;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    /**
     * 图片保存路径,自动从yml文件中获取数据
     *   示例: E:/uploadFile/
     */
    private String fileSavePath= "E:/uploadFile/";

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        /**
         * 配置资源映射
         * 意思是:如果访问的资源路径是以“/uploadFile/”开头的,
         * 就给我映射到本机的“E:/uploadFile/”这个文件夹内,去找你要的资源
         * 注意:E:/uploadFile/ 后面的 “/”一定要带上
         */
        registry.addResourceHandler("/uploadFile/**")
                .addResourceLocations("file:"+fileSavePath);
    }
}

之后同上进行测试。

这时上传后再重启项目,依然可以访问之前上传的文件。

静态资源位置除了classpath下面的4个路径之外,还有一个"/",因此这里的图片虽然是静态资源却可以直接访问到。

一文件上传的配置参数:

#是否开启文件上传支持,默认为true。
spring. servlet.multipart.enabled=true
#文件写入磁盘的阈值,默认为0。
spring.servlet.multipart.file-size-threshold=0
#上传文件的临时保存位置。
spring.servlet.multipart.location=E:ltemp
#上传的单个文件的最大大小,默认为1MB。
spring.servlet.multipart.max-file-size=1MB
#多文件上传时文件的总大小,默认为10MB。
spring.servlet.multipart.max-request-size=10MB
#文件是否延迟解析,默认为false。
spring.servlet.multipart.resolve-lazily=false

3.多文件上传

再上一个为基础进行修改,将原本接收的的MultipartFile对象变成数组

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FileUploadController {

    //以时间作为文件夹
    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");

    //文件存放的路径
    public static String fileSavePath="E:/uploadFile/";


    @PostMapping("/uploadPahtFiles")
    public static List uploadPahtFiles(MultipartFile[] uploadFiles, HttpServletRequest req) {
        //所传入文件项目访问路径的集合
        ArrayList filePathlist=new ArrayList();
        String filePath = "";
        for(MultipartFile uploadFile:uploadFiles){
            //如果文件名位空,则不保存
            if ("".equals(uploadFile.getOriginalFilename())){
                continue;
            }
            String format = sdf.format(new Date());
            File folder = new File(fileSavePath + format);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }
            String oldName = uploadFile.getOriginalFilename();
            String newName = UUID.randomUUID().toString() +
                    oldName.substring(oldName.lastIndexOf("."), oldName.length());
            try {
                uploadFile.transferTo(new File(folder, newName));
                filePath = req.getScheme() + "://" + req.getServerName() + ":" +
                        req.getServerPort() + "/uploadFile/" + format + newName;
            } catch (IOException e) {
                e.printStackTrace();
            }
            //将访问路径放入集合中
            filePathlist.add(filePath);
        }
        return filePathlist;
    }
}

:multiple="multiple" 是倍数(多选)的意思,再input标签中加上他就可以按Ctrl进行多选了。

4.整合为工具类

对其整合成工具类以便使用

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 文件上传工具类
 */
public class FileUploadUtil {

    //以时间作为文件夹
    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");

    //文件存放的路径
    public static String fileSavePath="E:/uploadFile/";

    /**
     * 上传文件到指定路径中,
     * 例如 fileSavePath=E:/uploadFile/"
     * @param uploadFile uploadPahtFile
     * @param req   request
     * @return 返回通过项目访问文件的路径(需要配置资源映射)
     */
    public static String uploadPahtFile(MultipartFile uploadFile, HttpServletRequest req) {
        if ("".equals(uploadFile.getOriginalFilename())){
            return "";
        }
        String filePath = "";
        String format = sdf.format(new Date());
        //固定物理路径
        File folder = new File(fileSavePath + format);
        //如果文件夹不存在则创建
        if (!folder.isDirectory()) {
            folder.mkdirs();//创建文件夹
        }
        //上传的文件名
        String oldName = uploadFile.getOriginalFilename();
        //新的文件名
        String newName = UUID.randomUUID().toString() +
                oldName.substring(oldName.lastIndexOf("."), oldName.length());
        try {
            //将uploadFile存到一个路径为:folder,名字为:newName的文件,
            uploadFile.transferTo(new File(folder, newName));
            //获取项目访问的路径
            filePath = req.getScheme() + "://" + req.getServerName() + ":" +
                    req.getServerPort() + "/uploadFile/" + format + newName;
        } catch (IOException e) {
            e.printStackTrace();
            return "上传失败! ";
        }
        return filePath;
    }

    /**
     * 上传文件到服务器路径,
     * 当上传过后项目再一次启动则会改变之前的路径,
     * 之前的文件也无法访问到了,但是还存在再电脑的临时文件夹 Temp 中
     * @param uploadFile 上传的文件
     * @param req request
     * @return 返回通过项目访问文件的路径(不需要配置资源映射)
     */
    public static String uploadServerFile(MultipartFile uploadFile, HttpServletRequest req) {
        if ("".equals(uploadFile.getOriginalFilename())){
            return "";
        }
        //文件存在的物理路径,但会随着项目的重新启动而改变
        String realPath =
                req.getSession().getServletContext().getRealPath("/uploadFile/");
        System.out.println(realPath);
        String format = sdf.format(new Date());
        File folder = new File(realPath + format);
        String filePath="";
        if (!folder.isDirectory()) {
            folder.mkdirs();
        }
        //当前文件名
        String oldName = uploadFile.getOriginalFilename();
        //新文件名
        String newName = UUID.randomUUID().toString() +
                oldName.substring(oldName.lastIndexOf("."), oldName.length());
        try {
            //将接收到的文件传输到给定的目标文件。
            uploadFile.transferTo(new File(folder, newName));
            //项目访问文件的路径
            filePath = req.getScheme() + "://" + req.getServerName() + ":" +
                    req.getServerPort() + "/uploadFile/" + format + newName;

        } catch (IOException e) {
            e.printStackTrace();
            return "上传失败! ";
        }
        return filePath;
    }

    /**
     * 上传多个文件到指定路径中
     * @param uploadFiles   uploadPahtFile
     * @param req request
     * @return 返回通过项目访问文件的路径的集合(需要配置资源映射)
     */
    public static List uploadPahtFiles(MultipartFile[] uploadFiles, HttpServletRequest req) {
        //所传入文件项目访问路径的集合
        ArrayList filePathlist=new ArrayList();
        String filePath = "";
        for(MultipartFile uploadFile:uploadFiles){
            //如果文件名位空,则不保存
            if ("".equals(uploadFile.getOriginalFilename())){
                continue;
            }
            String format = sdf.format(new Date());
            File folder = new File(fileSavePath + format);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }
            String oldName = uploadFile.getOriginalFilename();
            String newName = UUID.randomUUID().toString() +
                    oldName.substring(oldName.lastIndexOf("."), oldName.length());
            try {
                uploadFile.transferTo(new File(folder, newName));
                filePath = req.getScheme() + "://" + req.getServerName() + ":" +
                        req.getServerPort() + "/uploadFile/" + format + newName;
            } catch (IOException e) {
                e.printStackTrace();
            }
            //将访问路径放入集合中
            filePathlist.add(filePath);
        }
        return filePathlist;
    }


}

//配置资源映射的配置类
//@Configuration
//public class WebConfig implements WebMvcConfigurer {
//    /**
//     * 图片保存路径,自动从yml文件中获取数据
//     *   示例: E:/uploadFile/
//     */
//    private String fileSavePath= FileUploadUtil.fileSavePath;
//
//    @Override
//    public void addResourceHandlers(ResourceHandlerRegistry registry) {
//        /**
//         * 配置资源映射
//         * 意思是:如果访问的资源路径是以“/uploadFile/”开头的,
//         * 就给我映射到本机的“E:/uploadFile/”这个文件夹内,去找你要的资源
//         * 注意:E:/uploadFile/ 后面的 “/”一定要带上
//         */
//        registry.addResourceHandler("/uploadFile/**")
//                .addResourceLocations("file:"+fileSavePath);
//    }
//}

//文件上传的配置参数
//#是否开启文件上传支持,默认为true。
//spring. servlet.multipart.enabled=true
//#文件写入磁盘的阈值,默认为0。
//spring.servlet.multipart.file-size-threshold=0
//#上传文件的临时保存位置。
//spring.servlet.multipart.location=E:ltemp
//#上传的单个文件的最大大小,默认为1MB。
//spring.servlet.multipart.max-file-size=1MB
//#多文件上传时文件的总大小,默认为10MB。
//spring.servlet.multipart.max-request-size=10MB
//#文件是否延迟解析,默认为false。
//spring.servlet.multipart.resolve-lazily=false

以上就是Spring boot对文件的上传了。

你可能感兴趣的:(后端,前端,spring,boot,java,前端)