SpringMVC-文件上传

使用Apache发布的Commons FileUpload

  • Servlet 3.0规范已经提供方法来处理文件上传,但是这种上传需要在Servlet中完成
  • Spring MVC提供了更简单的封装, 使用即插即用的MultipartResolver实现
  • Spring MVC使用Apache发布的Commons FileUpload技术实现MultipartResolver类:CommonsMultipartResolver,所以SpringMVC的文件上传依赖Apache的Commons FileUpload
  1. 导入jar包: commons-fileupload,以及高版本的servlet

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
    </dependency>
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    </dependency>
  2. 配置bean: multipartResolver

    注意这个bean的id必须为multipartResolver,否则上传文件会报400的错误

    1
    2
    3
    4
    5
    6
    7
    8
    <!--文件上传配置-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--请求的编码格式,必须和jsp的pageEncoding一直,以便正确读取表单内容,默认IOS-8859-1-->
    <property name="defaultEncoding" value="utf-8"/>
    <!--上传文件大小上限,这里是10M-->
    <property name="maxUploadSize" value="10485760"/>
    <property name="maxInMemorySize" value="40960"/>
    </bean>
  3. 写一个简单的页面测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>$Title$</title>
    </head>
    <body>
    <form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="file"/>
    <input type="submit" value="upload">
    </form>
    </body>
    </html>
  4. Controller

    上传

    两种方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    package zone.yiqing.controller;

    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.commons.CommonsMultipartFile;

    import javax.servlet.http.HttpServletRequest;
    import java.io.*;

    /**
    * @Author Yiqing Zhang
    * @Date 2020-11-17 3:51 p.m.
    * @Version 1.0
    */
    @RestController
    public class FileController {

    /**
    * InputStream OutputSteaam
    * @param file
    * @param request
    * @return
    * @throws IOException
    */
    @RequestMapping("/upload")
    public String upload(@RequestParam("file")CommonsMultipartFile file, HttpServletRequest request) throws IOException {
    // 获取文件名
    String originalFilename = file.getOriginalFilename();

    // 文件名为空,返回首页
    if("".equals(originalFilename)){
    return "redirect:/index.jsp";
    }
    System.out.println("上传文件名: " + originalFilename);

    // 上传路径保存设置(可以使用UUID)
    String path = request.getServletContext().getRealPath("/upload");
    // 如果路径不存在,创建
    File realPath = new File(path);
    if(!realPath.exists()){
    realPath.mkdir();
    }
    System.out.println("文件上传保存地址: " + realPath);

    InputStream inputStream = file.getInputStream();// 文件输入流
    OutputStream outputStream = new FileOutputStream(new File(realPath, originalFilename));// 文件输出流

    // 读取写出
    int len = 0;
    byte[] buffer = new byte[1024];
    while ((len=inputStream.read(buffer))!=-1){
    outputStream.write(buffer,0,len);
    outputStream.flush();
    }
    outputStream.close();
    inputStream.close();

    return "redirect:/index.jsp";
    }

    /**
    * 采用file.Transto 来保存
    * @param file
    * @param request
    * @return
    * @throws IOException
    */
    @RequestMapping("/upload2")
    public String upload2(@RequestParam("file")CommonsMultipartFile file, HttpServletRequest request) throws IOException{

    // 上传路径保存设置
    String path = request.getServletContext().getRealPath("/upload");
    // 如果路径不存在,创建
    File realPath = new File(path);
    if(!realPath.exists()){
    realPath.mkdir();
    }
    System.out.println("文件上传保存地址: " + realPath);

    // 通过CommonsMultipartFile的方法直接写文件
    file.transferTo(new File(realPath + "/" + file.getOriginalFilename()));;

    return "redirect:/index.jsp";
    }
    }

    下载

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    @RequestMapping("/download")
    public String download(HttpServletResponse response, HttpServletRequest request) throws Exception{
    // 要下载的地址
    String path = request.getServletContext().getRealPath("/upload");
    String fileName = "xxx.jpg";

    // 1. 设置response响应头
    response.reset(); // 设置页面不缓存,清空buffer
    response.setContentType("multipart/form-data"); // 二进制传输数据
    response.setHeader("Content-Disposition","attachment;fileName="+ URLEncoder.encode(fileName,"UTF-8"));

    File file = new File(path,fileName);
    // 2. 读取文件---输入流
    InputStream inputStream = new FileInputStream(file);
    // 3. 写入文件---输出流
    OutputStream outputStream = response.getOutputStream();

    byte[] buffer = new byte[1024];
    int index = 0;
    while ((index=inputStream.read(buffer)) != -1){
    outputStream.write(buffer,0,index);
    outputStream.flush();
    }
    outputStream.close();
    inputStream.close();

    return null;
    }