12

SpringBoot系列(九)单,多文件上传的正确姿势

 4 years ago
source link: http://www.cnblogs.com/swzx-1213/p/12756239.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

SpringBoot系列(九)分分钟解决文件上传

SpringBoot系列(二)入门知识

springBoot系列(三)配置文件详解

SpringBoot系列(四)web静态资源配置详解

SpringBoot系列(五)Mybatis整合完整详细版

SpringBoot系列(六)集成thymeleaf详解版

Springboot系列(七) 集成接口文档swagger,使用,测试

SpringBoot系列(八)分分钟学会Springboot多种解决跨域方式

1.项目搭建与配置

我们直接创建一个包含 web 依赖的项目就好了。

然后需要在配置文件配置文件上传的一些设置。这里使用 yml 文件作为配置文件,如果不懂语法的,请移步前面的 系列三 ,里面有详细解释。

server:
  port: 8095

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 30MB
  • max-file-size 设置能接受的文件最大的大小,记得是 MB,或KB
  • max-request-size 设置 一次 上传的所有文件的大小。

默认大小为1MB

除了可以用配置文件配置还可利用java配置,如下

@Bean
public MultipartConfigElement multipartConfigElement() {
    MultipartConfigFactory factory = new MultipartConfigFactory();
    //上传的单个文件最大值   KB,MB 这里设置为10MB
    DataSize maxSize = DataSize.ofMegabytes(10);
    DataSize requestMaxSize = DataSize.ofMegabytes(30);
    factory.setMaxFileSize(maxSize);
    /// 设置一次上传文件的总大小
    factory.setMaxRequestSize(requestMaxSize);
    return factory.createMultipartConfig();
}

这个方法可以放在 启动类 里面,也可以自己放置在一个 配置类 里面,让项目启动的时候能正常加载就行。

2.文件上传

单文件上传,我们需要用后端接受并将文件存储到 项目里面 或者是 自己定义路径 。这里以图片作为上传的文件。并且将文件上传到项目里面。

@RestController
@RequestMapping("/file")
public class FileController {
    @PostMapping("/uploadFile")
    public String uploadFile(MultipartFile file, HttpServletRequest request)  {
        if (file.isEmpty()){
            return "上传的文件不能为空!请重新上传";
        }
        if (file.getSize()<=0){
            return "上传的文件大小需要大于0kb";
        }
        System.out.println(file.getContentType());//image/png
        Date date = new Date();
        Long time = date.getTime();
        String originFileName = file.getOriginalFilename();//获取文件原始的名称
        String newFileName = time+originFileName;
        //获取项目运行的绝对路径
        String filePath = System.getProperty("user.dir");

        //由于我是创建的多模块项目,所以获取到的项目运行路径为外层的项目路径,
        // 这时候我们就需要在项目相对路径这里加上项目的名称demo-upload
        String newFilePath = filePath+"\\demo-upload\\src\\main\\resources\\static\\images\\";

        //当然你也可以自己设置一个绝对路径用于图片上传,文件上传。
        //比如说:D:\\images\\
        File file1 = new File(newFilePath);

        if (!file1.exists()){
            file1.mkdirs();
        }
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(newFilePath+newFileName);
            fileOutputStream.write(file.getBytes());
            fileOutputStream.flush();
            fileOutputStream.close();
            return "localhost:8095/images/"+newFileName;
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
        return "上传失败";
    }
}

代码说明:

在代码里,我们可以利用参数 file 来判断这个文件是否为空,或者将这个文件的后缀名拿出来,判断这个文件的类型是否符合我们的要求,利用 getContentType() 方法,如果你是上传的png图片,那么打印出来的就是 image/png 其他类型的图片就是其他类型。我们为了区分图片,可以利用当前时间的getTime方法获得的数字来作为图片的前缀,也可以用其他的数字或者字符串。都不想说了,码字太累了。接下来获取当前项目运行的路径,由于我是创建的 多模块项目 ,所以这个获取的路径需要再加上 项目名称 ,后面加上我们需要上传的文件存储的位置,一般在resources文件下面。然后判断这个存储文件的文件夹是否存在,如果不存在就需要创建一个文件。然后利用字节流,将数据写到文件中,返回可访问的路径。

前端代码,我直接在static目录下面创建了一个upload.html文件,然后我们在文件里面写入一下内容

<p>单文件上传</p>
<form action="/file/uploadFile" method="POST" enctype="multipart/form-data">
    文件:<input type="file" name="file"/>
    <input type="submit" />
</form>

它的 action 对应了我们controller里面访问上传文件的对应的方法的路径,method属性是post,与后端一致。type为file的input框的 name属性 需要与controller里面的接受对象 MultipartFile 一致,如果不一致的话后端无法接受到数据。如果你已经写好后端,而前端后端参数不一致,你可以给后端参数加上一个注解。 @RequestParam("file") 这个注解放在MultipartFile的前面,这样即使你的参数名字不是file,也能正确接受到数据。

将文件上传之后,那个返回的路径应该是不能直接访问到图片的,会显示404,我们需可以添加以下配置。

@Configuration
public class ResourceConfigAdapter implements WebMvcConfigurer {


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //获取文件的真实路径
        String path = System.getProperty("user.dir")+"\\demo-upload\\src\\main\\resources\\static\\images\\";
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            registry.addResourceHandler("/images/**").
                    addResourceLocations("file:" + path);
        }

    }
}

这里的java动态配置比利用的yml的配置更灵活,在知道文件要存储的位置的情况下,可以自己在yml文件里面加配置。然后我们运行项目,如下:

Njyyqq3.png!web

上传一张图片,返回可访问的路径

qAf6Rbu.png!web

然后我们将这个URL复制到浏览器,运行,就能访问图片了。

这是单文件上传,然后可能你需要做多文件上传,很简单,后端做一个循环就行了,然后利用MultipartFile的 数组 接受文件,对前端做一点修改。

@PostMapping("/uploadFiles")
public String uploadFiles(MultipartFile[] files,HttpServletRequest request) {
    StringBuilder paths = new StringBuilder();
    for (MultipartFile file:files) {
        //中间的代码和上面的一样
        try {
            //这里根据实际情况修改,可以用数组
            paths.append("localhost:8095/images/"+newFileName+"\n");
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
    }
    return paths.toString();
}

前端稍微修改一下

<p>多文件上传</p>

<form action="/file/uploadFiles" method="POST" enctype="multipart/form-data">
    文件:<input type="file" name="files" multiple="multiple"/>
    <input type="submit"/>
</form>

这就完成了多文件的上传,在上传的时候你需要按住 Ctrl键 ,然后选中多个文件,就能上传了。

3.总结

本文讲解了单文件,多文件上传,然后对文件的上传限制条件与访问添加了一些配置。如果你觉得本文对你有用,点个赞表示一下。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK