• SpringBoot 2.x (3):文件上传


    文件上传有两个要点

    一是如何高效地上传:使用MultipartFile替代FileOutputSteam

    二是上传文件的路径问题的解决:使用路径映射

    文件路径通常不在classpath,而是本地的一个固定路径或者是一个文件服务器路径

    SpringBoot的路径:

    src/main/java:存放代码

    src/main/resources:存放资源

      static: 存放静态文件:css、js、image (访问方式 http://localhost:8080/js/main.js)

      templates:存放静态页面:html,jsp

      application.properties:配置文件

    但是要注意:

    比如我在static下新建index.html,那么就可以访问localhost:8080/index.html看到页面

    如果在templates下新建index.html,那么访问会显示错误,除非在Controller中进行跳转

    如果想对默认静态资源路径进行修改,则在application.properties中配置:

    spring.resources.static-locations = classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ 

    这里默认的顺序是先从/META-INF/resources中进行寻找,最后找到/public,可以在后边自行添加

    文件上传不是老问题,这里就当是巩固学习了

    方式:MultipartFile file,源自SpringMVC

    首先需要一个文件上传的页面

    在static目录下新建一个html页面:

    <!DOCTYPE html>
    <html>
    <head>
    <title>文件上传</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body>
        <form enctype="multipart/form-data" method="post" action="/upload">
            文件:<input type="file" name="head_img" /> 姓名:<input type="text"
                name="name" /> <input type="submit" value="上传" />
        </form>
    </body>
    </html>

    文件上传成功否需要返回的应该是一个封装的对象:

    package org.dreamtech.springboot.domain;
    
    import java.io.Serializable;
    
    public class FileData implements Serializable {
        private static final long serialVersionUID = 8573440386723294606L;
        // 返回状态码:0失败、1成功
        private int code;
        // 返回数据
        private Object data;
        // 错误信息
        private String errMsg;
    
        public int getCode() {
            return code;
        }
    
        public void setCode(int code) {
            this.code = code;
        }
    
        public Object getData() {
            return data;
        }
    
        public void setData(Object data) {
            this.data = data;
        }
    
        public String getErrMsg() {
            return errMsg;
        }
    
        public void setErrMsg(String errMsg) {
            this.errMsg = errMsg;
        }
    
        public FileData(int code, Object data) {
            super();
            this.code = code;
            this.data = data;
        }
    
        public FileData(int code, Object data, String errMsg) {
            super();
            this.code = code;
            this.data = data;
            this.errMsg = errMsg;
        }
    
    }

    处理文件上传的Controller:

    package org.dreamtech.springboot.controller;
    
    import java.io.File;
    import java.util.UUID;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.dreamtech.springboot.domain.FileData;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    @RestController
    public class FileController {
        private static final String FILE_PATH = "D:\temp\images\";
        static {
            File file = new File(FILE_PATH);
            if (!file.exists()) {
                file.mkdirs();
            }
        }
    
        @RequestMapping("/upload")
        private FileData upload(@RequestParam("head_img") MultipartFile file, HttpServletRequest request) {
            if (file.isEmpty()) {
                return new FileData(0, null, "文件不能为空");
            }
            String name = request.getParameter("name");
            System.out.println("用户名:" + name);
            String fileName = file.getOriginalFilename();
            System.out.println("文件名:" + fileName);
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            System.out.println("后缀名:" + suffixName);
            fileName = UUID.randomUUID() + suffixName;
            String path = FILE_PATH + fileName;
            File dest = new File(path);
            System.out.println("文件路径:" + path);
            try {
                // transferTo文件保存方法效率很高
                file.transferTo(dest);
                System.out.println("文件上传成功");
                return new FileData(1, fileName);
            } catch (Exception e) {
                e.printStackTrace();
                return new FileData(0, fileName, e.toString());
            }
        }
    }

    还有问题要处理,保存图片的路径不是项目路径,而是本地的一个固定路径,那么要如何通过URL访问到图片呢?

    对路径进行映射:比如我图片保存在D: empimage,那么我们希望访问localhost:8080/image/xxx.png得到图片

    可以修改Tomcat的配置文件,也可以按照下面的配置:

    package org.dreamtech.springboot.config;
    
    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 MyWebAppConfigurer implements WebMvcConfigurer {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/image/**").addResourceLocations("file:D:/temp/images/");
        }
    }

    还有一些细节问题不得忽略:对文件大小进行限制

    package org.dreamtech.springboot.config;
    
    import javax.servlet.MultipartConfigElement;
    
    import org.springframework.boot.web.servlet.MultipartConfigFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.util.unit.DataSize;
    
    @Configuration
    public class FileSizeConfigurer {
        @Bean
        public MultipartConfigElement multipartConfigElement() {
            MultipartConfigFactory factory = new MultipartConfigFactory();
            // 单个文件最大10MB
            factory.setMaxFileSize(DataSize.ofMegabytes(10L));
            /// 设置总上传数据总大小10GB
            factory.setMaxRequestSize(DataSize.ofGigabytes(10L));
            return factory.createMultipartConfig();
        }
    }

    打包后的项目如何处理文件上传呢?

    顺便记录SpringBoot打包的坑,mvn clean package运行没有问题,但是不太方便

    于是eclipse中run as maven install,但是会报错,根本原因是没有配置JDK,配置的是JRE:

    解决:https://blog.csdn.net/lslk9898/article/details/73836745

    图片量不大的时候,我们可以用自己的服务器自行处理,

    如果图片量很多,可以采用图片服务器,自己用Nginx搭建或者阿里OSS等等

  • 相关阅读:
    如何恢复包含损坏记录的物理文件
    启动日志
    如何在各种环境中处理多成员的物理文件
    如何找出物理文件中损坏的记录
    如何重新找回物理文件中已经被删除的记录
    folder的操作
    如何将AS/400英文界面改为中文界面?
    如何从OS/400里直接发送电子邮件到Internet
    如何在AS/400上发送带有颜色的MESSAGE
    关于命令RGZPFM
  • 原文地址:https://www.cnblogs.com/xuyiqing/p/10806347.html
Copyright © 2020-2023  润新知