SpringMVC(六)文件上传

SpringMVC(六)文件上传

Spring MVC对上传文件的支持

首先,DispatcherServlet会使用适配器模式,将HttpServletRequest接口对象转换为MultipartHttpServertRequest对象。MultipartHttpServetRequest接口拓展了HttpServletRequest接口的所有方法,而且定义了一些操作文件的方法,这样通过这些方法就可以实现对上传文件的操作。

SpringMVC(六)文件上传
可以看到,MultipartHttpServetRequest接口的作用是,通过类的适配加入原有HTTP请求对象的功能,并扩展文件操作功能。

文件上传配置

# springMVC文件上传配置
# MULTIPART(multipartProperties)
# 是否启用soring mvc多分部上传功能
spring.servlet.multipart.enabled=true
# 将文件写入磁盘的阈值。只可以使用后缀"MB"或者"KB"来表示兆字节或字节大小
spring.servlet.multipart.file-size-threshold=0
# 指定默认上传的文件夹
spring.servlet.multipart.location=
# 限制单个文件最大大小
spring.servlet.multipart.max-file-size=1MB
# 先直所有文件最大大小
spring.servlet.multipart.max-request-size=10MB
# 是否延迟多部分文件请求的参数和文件的解析
spring.servlet.multipart.resolve-lazily=false

根据这些配置,spring boot会自动生成StandardServletMultipartResolver对象,这样就能能够对上传文件进行配置。对于文件的上传可以使用sevlet api提供的Part接口或者spring mvc提供的MultipartFile接口作为参数。

文件上传

application.properties配置文件

# 指定默认上传的文件夹
spring.servlet.multipart.location=e:/springboot
# 限制单个文件最大大小,这里设置为5MB
spring.servlet.multipart.max-file-size=5242880
# 限制所有文件最大大小,这里设置为20MB
spring.servlet.multipart.max-request-size=20MB

这里设置了上传的目标文件夹为e:/pringboot目录,并且指定单个文件大小为5MB,所有文件最大为20MB。

为了测试文件的上传,我们使用thymeleaf作为模板写一个HTML文件。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
    <form method="post" action="./request", enctype="multipart/form-data">
        <input type="file" name="file" value="请选择上传文件"/>
        <input type="submit" value="提交"/>
    </form>

</body>
</html>

这里表单声明为muiltipart/form-data,如果没有这个声明,Spring MVC就会解析文件请求出错,从而导致上传文件失败。

开发控制器

package com.lay.mvc.controller;

/**
 * @Description:文件上传控制器
 * @Author: lay
 * @Date: Created in 19:55 2018/11/14
 * @Modified By:IntelliJ IDEA
 */
@Controller
public class FileController {
    //上传页面展示
    @GetMapping("/upload/page")
    public String uploadPage(){
        return "/file/upload";
    }
    /**
     *
     * @Description: 处理上传文件结果
     * @param: [success, msg]
     * @return: java.util.Map<java.lang.String,java.lang.Object>
     * @auther: lay
     * @date: 10:50 2018/11/15
     */
    private Map<String,Object> dealResultMap(boolean success,String msg){
        Map<String,Object> result=new HashMap<>();
        result.put("success",success);
        result.put("msg",msg);
        return result;
    }


}

HttpServletRequest

/**
     *
     * @Description: 使用HttpServletRequest作为参数
     * @param: [request]
     * @return: java.util.Map<java.lang.String,java.lang.Object>
     * @auther: lay
     * @date: 11:10 2018/11/15
     */
    @PostMapping("/upload/request")
    @ResponseBody
    public Map<String,Object> uploadRequest(HttpServletRequest request){
        boolean flag=false;
        MultipartHttpServletRequest mreq=null;
        //强制转换为MultipartHttpServletRequest接口对象
        if(request instanceof MultipartHttpServletRequest){
            mreq=(MultipartHttpServletRequest)request;
        }else {
            return dealResultMap(false,"上传失败");
        }
        //获取MultipartFile文件
        MultipartFile mf=mreq.getFile("file");
        //获取源文件名称
        String fileName=mf.getOriginalFilename();
        File file=new File(fileName);
        try {
            //保存文件
            mf.transferTo(file);
        }catch (Exception e){
            e.printStackTrace();
            return dealResultMap(false,"上传失败");
        }
        return dealResultMap(true,"上传成功");
    }

MultiPartFile

 //使用Spring MVC 的MultipartFille类作为参数
    @PostMapping("/upload/multipart")
    @ResponseBody
    public Map<String,Object> uploadMultipartFile(MultipartFile file){
        String fileName=file.getOriginalFilename();
        File dest=new File(fileName);
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            e.printStackTrace();
            return dealResultMap(false,"上传失败");
        }
        return dealResultMap(true,"上传成功");
    }

Part

 /**
     *
     * @Description: 使用Part接口作为参数
     * @param: [success, msg]
     * @return: java.util.Map<java.lang.String,java.lang.Object>
     * @auther: lay
     * @date: 10:36 2018/11/15
     */
    @PostMapping("/upload/part")
    @ResponseBody
    public Map<String,Object> uploadPart(Part file){
        //获取提交文件名称
        String fileName=file.getSubmittedFileName();
        try {
            file.write(fileName);
        } catch (IOException e) {
            e.printStackTrace();
            return dealResultMap(false,"上传失败");
        }
        return dealResultMap(true,"上传成功");
    }