zoukankan      html  css  js  c++  java
  • 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等等

  • 相关阅读:
    HDOJ 1207 汉诺塔II
    [转]写代码的小女孩
    POJ Subway tree systems
    HDOJ 3555 Bomb (数位DP)
    POJ 1636 Prison rearrangement (DP)
    POJ 1015 Jury Compromise (DP)
    UVA 10003
    UVA 103 Stacking Boxes
    HDOJ 3530 Subsequence
    第三百六十二、三天 how can I 坚持
  • 原文地址:https://www.cnblogs.com/xuyiqing/p/10806347.html
Copyright © 2011-2022 走看看