springMVC文件上传

132 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情 ​ ​ ​

 Spring MVC 框架的文件上传基于 commons-fileupload 组件,并在该组件上做了进一步的封装,简化了文件上传的代码实现,取消了不同上传组件上的编程差异。

MultipartResolver接口

在 Spring MVC 中实现文件上传十分容易,它为文件上传提供了直接支持,即 MultpartiResolver 接口。MultipartResolver 用于处理上传请求,将上传请求包装成可以直接获取文件的数据,从而方便操作。

MultpartiResolver 接口有以下两个实现类:

  • StandardServletMultipartResolver:使用了 Servlet 3.0 标准的上传方式。
  • CommonsMultipartResolver:使用了 Apache 的 commons-fileupload 来完成具体的上传操作。

MultpartiResolver 接口具有以下方法。

名称作用
byte[] getBytes()以字节数组的形式返回文件的内容
String getContentType()返回文件的内容类型
InputStream getInputStream()返回一个InputStream,从中读取文件的内容
String getName()返回请求参数的名称
String getOriginalFillename()返回客户端提交的原始文件名称
long getSize()返回文件的大小,单位为字节
boolean isEmpty()判断被上传文件是否为空
void transferTo(File destination)将上传文件保存到目标目录下

单文件上传

1.maven引入

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.11.0</version>
</dependency>

  1. 配置 MultipartResolver

使用 CommonsMultipartReslover 配置 MultipartResolver 解析器,在 springmvc-servlet.xml 中添加代码如下。

<!-- 配置MultipartResolver,用于上传文件,使用spring的CommonsMultipartResolver -->
<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="5000000" />
    <property name="defaultEncoding" value="UTF-8" />
</bean>

  • defaultEncoding:请求的编码格式,默认为 ISO-8859-1,此处设置为 UTF-8(注:defaultEncoding 必须和 JSP 中的 pageEncoding 一致,以便正确读取表单的内容)。
  • maxUploadSize:上传文件大小上限,单位为字节。

3.编写文件上传表单页面

负责文件上传表单的编码类型必须是“multipart/form-data”类型。

<form action="/upload" method="post" enctype="multipart/form-data">
    文件:<input type="file" name="multipartFile"><br>
    <input type="submit" value="上传">
</form>

备注: file 文件的name参数值与控制器类中的参数值保持一致。

  1. 编写控制器
@RestController
public class UploadController {

    @PostMapping("/upload")
    public String upload(MultipartFile multipartFile, HttpServletRequest request){

        //获取服务器根路径
        String root=request.getSession().getServletContext().getRealPath("/");
        //创建服务器附件的路径
        File dir=new File(root+"/attachment");
        //先判断目录 是否存在
        if(!dir.exists()){
            //创建目录
            dir.mkdir();
        }

        //获取原文件的后缀
        String name=multipartFile.getOriginalFilename();
        String ext=name.substring(name.lastIndexOf("."));
        String newFileName=System.currentTimeMillis()+ext;
        //要上传到服务上的新的文件
        File newFile=new File(dir,newFileName);

        try {
            multipartFile.transferTo(newFile);
            return "attachment/"+newFileName;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

多文件上传:

<form action="/batchUpload" method="post" enctype="multipart/form-data">
    文件:<input type="file" name="multipartFiles"><br>
    <input type="file" name="multipartFiles"><br>
    <input type="file" name="multipartFiles"><br>
    <input type="submit" value="上传">
</form>

控制类

实现只要将参数改成List multipartFiles即可。

@RestController // 注册到ioc容器
@PropertySource("classpath:file.properties")
public class UploadController {

    final String ATTACHMENT_DIRS="/attachment/";
    final int  SUCCESS=200;
    final int FAIL=0;

    String root; //服务器根路径

    @Autowired
    HttpServletRequest req;

    @Value("${upload.maxSize}")
    long maxSize;

    @Value("${upload.type}")
    String type;


    @PostMapping("/upload")
    public UploadBean upload(MultipartFile multipartFile){
        createDir();
        return writeFile(multipartFile);
    }


    @PostMapping("/batchUpload")
    public List uploadMulitFile(List<MultipartFile> multipartFiles){
        createDir();
        List list=new ArrayList();
        //遍历文件 列表
        Iterator<MultipartFile> it=multipartFiles.iterator();
        while (it.hasNext()){
            MultipartFile file=it.next();
            list.add(writeFile(file));
        }
        return list;
    }


    void createDir(){
        //获取服务器根路径
        //创建服务器附件的路径
        File dir=new File(getRoot()+ATTACHMENT_DIRS);
        //先判断目录 是否存在
        if(!dir.exists()){
            //创建目录
            dir.mkdir();
        }
    }

    /**
     * 将文件 写入服务器
     * @param file
     * @return
     */
    UploadBean writeFile(MultipartFile file){
        if(file.isEmpty())
            return fail("上传的文件为空");
        //获取文件类型
        String ct=file.getContentType();
        if(type.indexOf(ct)==-1){
            return fail("暂不支持该格式的文件上传");
        }

        if(file.getSize()>maxSize){
            return fail("文件超过最大上传限制");
        }

        //获取新文件 名
        String fileName=getNewFileName(file);
        //创建新的文件
        File newFile=new File(getRoot()+ATTACHMENT_DIRS+fileName);
        //将文件写入服务器
        try {
            file.transferTo(newFile);
            return success(ATTACHMENT_DIRS+fileName);
        } catch (IOException e) {
            e.printStackTrace();
            return fail("上传失败:"+e.toString());
        }
    }

    /**
     * 生成新的文件名
     * @param file
     * @return
     */
    String getNewFileName(MultipartFile file){
        //获取原文件的后缀
        String name=file.getOriginalFilename();
        String ext=name.substring(name.lastIndexOf("."));
        String newFileName=System.currentTimeMillis()+ext;
        return newFileName;
    }

    public String getRoot() {
        if(null==root && null!=req){
            root=req.getSession().getServletContext().getRealPath("/");
        }
        return root;
    }

    UploadBean success(Object data){
        return new UploadBean(SUCCESS,"上传成功",data);
    }

    UploadBean fail(String msg){
        return new UploadBean(FAIL,msg,null);
    }
}

file.properties文件内容:

upload.maxSize=10485760
upload.type=image/jpeg,image/png  

UploadBean.java

public class UploadBean {
    int code;
    String msg;
    Object data;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public UploadBean(int code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public UploadBean() {
    }
}

\