吴裕雄天生自然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);
    }
}

 

 

原文地址:https://www.cnblogs.com/tszr/p/15333502.html