• 吴裕雄天生自然Spring BootSpring Boot文件上传与下载


     从Servlet 3.0开始,就提供了处理文件上传的方法,但这种文件上传需要在Java Servlet中完成,而Spring MVC提供了更简单的封装。Spring MVC是通过Apache Commons FileUpload技术实现一个MultipartResolver的实现类CommonsMultipartResolver完成文件上传的。因此,Spring MVC的文件上传需要依赖Apache Commons FileUpload组件。
        Spring MVC将上传文件自动绑定到MultipartFile对象中,MultipartFile提供了获取上传文件内容、文件名等方法,并通过transferTo方法将文件上传到服务器的磁盘中,MultipartFile的常用方法如下:
        byte[] getBytes():获取文件数据。
        String getContentType():获取文件MIME类型,如image/jpeg等。
        InputStream getInputStream():获取文件流。
        String getName():获取表单中文件组件的名字。
        String getOriginalFilename():获取上传文件的原名。
        long getSize():获取文件的字节大小,单位为byte。
        boolean isEmpty():是否有(选择)上传文件。
        void transferTo(File dest):将上传文件保存到一个目标文件中。
        Spring Boot的spring-boot-starter-web已经集成了Spring MVC,所以使用Spring Boot实现文件上传,更加便捷,只需要引入Apache Commons FileUpload组件依赖即可。
    1.引入Apache Commons FileUpload组件依赖
    2.设置上传文件大小限制
    3.创建选择文件视图页面
    4.创建控制器
    5.创建文件下载视图页面
    6.运行
    添加Apache Commons FileUpload组件依赖,具体代码如下:
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <!-- 由于commons-fileupload组件不属于Spring Boot,所以需要加上版本 -->
            <version>1.3.3</version>
        </dependency>
    配置文件application.properties中,添加如下配置进行限制上传文件大小。
    #上传文件时,默认单个上传文件大小是1MB,max-file-size设置单个上传文件大小
    spring.servlet.multipart.max-file-size=50MB
    #默认总文件大小是10MB,max-request-size设置总上传文件大小
    spring.servlet.multipart.max-request-size=500MB
    创建控制器类TestFileUpload。在该类中有4个处理方法,一个是界面导航方法uploadFile,一个是实现文件上传的upload方法,一个是显示将要被下载文件的showDownLoad方法,一个是实现下载功能的download方法。
    应用的src/main/resources/templates目录下,创建文件下载视图页面showFile.html。
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.kdjfda</groupId>
      <artifactId>SpringBoot-File</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      
      <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.0.RELEASE</version>
            <relativePath /> <!-- lookup parent from repository -->
        </parent>
        
        <properties>
            <!-- 声明项目配置依赖编码格式为 utf-8 -->
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <fastjson.version>1.2.24</fastjson.version>
        </properties>
        
        <dependencies>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <!-- 由于commons-fileupload组件不属于Spring Boot,所以需要加上版本 -->
                <version>1.3.3</version>
            </dependency>
            
        </dependencies>
      
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
    server.servlet.context-path=/ch5_2
    spring.servlet.multipart.max-file-size=50MB
    spring.servlet.multipart.max-request-size=500MB
    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <link rel="stylesheet" th:href="@{css/bootstrap.min.css}" />
    <!-- 默认访问 src/main/resources/static下的css文件夹-->
    <link rel="stylesheet" th:href="@{css/bootstrap-theme.min.css}" />
    </head>
    <body>
    <div class="panel panel-primary">
            <div class="panel-heading">
                <h3 class="panel-title">文件上传示例</h3>
            </div>
        </div>
        <div class="container">
            <div class="row">
                <div class="col-md-6 col-sm-6">
                    <form class="form-horizontal" action="upload" method="post" enctype="multipart/form-data">
                        <div class="form-group">
                            <div class="input-group col-md-6">
                                <span class="input-group-addon">
                                    <i class="glyphicon glyphicon-pencil"></i>
                                </span>
                                <input class="form-control" type="text"
                                 name="description" th:placeholder="文件描述"/>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="input-group col-md-6">
                                <span class="input-group-addon">
                                    <i class="glyphicon glyphicon-search"></i>
                                </span>
                                <input class="form-control" type="file"
                                 name="myfile" th:placeholder="请选择文件"/>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-6">
                                <div class="btn-group btn-group-justified">
                                    <div class="btn-group">
                                        <button type="submit" class="btn btn-success">
                                            <span class="glyphicon glyphicon-share"></span>
                                            &nbsp;上传文件
                                        </button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </body>
    </html>
    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <link rel="stylesheet" th:href="@{css/bootstrap.min.css}" />
    <!-- 默认访问 src/main/resources/static下的css文件夹-->
    <link rel="stylesheet" th:href="@{css/bootstrap-theme.min.css}" />
    <body>
        <div class="panel panel-primary">
            <div class="panel-heading">
                <h3 class="panel-title">文件下载示例</h3>
            </div>
        </div>
        <div class="container">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    <h3 class="panel-title">文件列表</h3>
                </div>
                <div class="panel-body">
                    <div class="table table-responsive">
                        <table class="table table-bordered table-hover">
                            <tbody class="text-center">
                                <tr th:each="file,fileStat:${filesList}">
                                    <td>
                                        <span th:text="${fileStat.count}"></span>
                                    </td>
                                    <td>
                                        <!--file.name相当于调用getName()方法获得文件名称  -->
                                        <a th:href="@{download(filename=${file.name})}">
                                            <span th:text="${file.name}"></span>
                                        </a>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </body>
    </html>
    package com.ch.ch5_2.controller;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.URLEncoder;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.commons.io.FileUtils;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.http.ResponseEntity.BodyBuilder;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestHeader;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.multipart.MultipartFile;
    
    @Controller
    public class TestFileUpload {
        /**
         * 进入文件选择页面
         */
        @RequestMapping("/uploadFile")
        public String uploadFile() {
            return "uploadFile";
        }
    
        /**
         * 上传文件自动绑定到MultipartFile对象中, 在这里使用处理方法的形参接收请求参数。
         * 
         * @throws IOException
         * @throws IllegalStateException
         */
        @RequestMapping("/upload")
        public String upload(HttpServletRequest request, @RequestParam("description") String description,
                @RequestParam("myfile") MultipartFile myfile) throws IllegalStateException, IOException {
            System.out.println("文件描述:" + description);
            // 如果选择了上传文件,将文件上传到指定的目录uploadFiles
            if (!myfile.isEmpty()) {
                // 上传文件路径
                String path = request.getServletContext().getRealPath("/uploadFiles/");
                // 获得上传文件原名
                String fileName = myfile.getOriginalFilename();
                File filePath = new File(path + File.separator + fileName);
                // 如果文件目录不存在,创建目录
                if (!filePath.getParentFile().exists()) {
                    filePath.getParentFile().mkdirs();
                }
                // 将上传文件保存到一个目标文件中
                myfile.transferTo(filePath);
            }
            // 转发到一个请求处理方法,查询将要下载的文件
            return "forward:/showDownLoad";
        }
    
        /**
         * 显示要下载的文件
         */
        @RequestMapping("/showDownLoad")
        public String showDownLoad(HttpServletRequest request, Model model) {
            String path = request.getServletContext().getRealPath("/uploadFiles/");
            File fileDir = new File(path);
            // 从指定目录获得文件列表
            File filesList[] = fileDir.listFiles();
            model.addAttribute("filesList", filesList);
            return "showFile";
        }
    
        /**
         * 实现下载功能
         * 
         * @throws IOException
         */
        @RequestMapping("/download")
        public ResponseEntity<byte[]> download(HttpServletRequest request, @RequestParam("filename") String filename,
                @RequestHeader("User-Agent") String userAgent) throws IOException {
            // 下载文件路径
            String path = request.getServletContext().getRealPath("/uploadFiles/");
            // 构建将要下载的文件对象
            File downFile = new File(path + File.separator + filename);
            // ok表示HTTP中的状态是200
            BodyBuilder builder = ResponseEntity.ok();
            // 内容长度
            builder.contentLength(downFile.length());
            // application/octet-stream:二进制流数据(最常见的文件下载)
            builder.contentType(MediaType.APPLICATION_OCTET_STREAM);
            // 使用URLEncoder.encode对文件名进行编码
            filename = URLEncoder.encode(filename, "UTF-8");
            /**
             * 设置实际的响应文件名,告诉浏览器文件要用于“下载”和“保存”。 不同的浏览器,处理方式不同,根据浏览器的实际情况区别对待。
             */
            if (userAgent.indexOf("MSIE") > 0) {
                // IE浏览器,只需要用UTF-8字符集进行URL编码
                builder.header("Content-Disposition", "attachment; filename=" + filename);
            } else {
                /**
                 * 非IE浏览器,如FireFox、Chrome等浏览器,则需要说明编码的字符集 filename后面有个*号,在UTF-8后面有两个单引号
                 */
                builder.header("Content-Disposition", "attachment; filename*=UTF-8''" + filename);
            }
            return builder.body(FileUtils.readFileToByteArray(downFile));
        }
    }
    package com.ch.ch5_2;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class Ch52Application {
        public static void main(String[] args) {
            SpringApplication.run(Ch52Application.class, args);
        }
    }

     

     

  • 相关阅读:
    JavaScript 、ECMAScript、commonJS 发展历史 与标准化发展
    jquey的 ajax请求的几种方式
    Flask web开发 处理Ajax请求
    Python 2.7 学习笔记 面向对象的编程
    Python 2.7 学习笔记 访问mysql数据库
    UI基础七:给普通其他界面的PRODUCT 添加标准的搜索帮助
    函数使用十二:BAPI_MATERIAL_BOM_GROUP_CREATE(CS61)
    ABAP游标
    UI基础六:UI报弹窗确认
    WDA基础十四:ALV字段属性配置表
  • 原文地址:https://www.cnblogs.com/tszr/p/15333502.html
Copyright © 2020-2023  润新知