Spring MVC 入门指南(十二):单文件上传与多文件上传

一、简述

一个javaWeb项目中,文件上传功能几乎是必不可少的,本人在项目开发中也时常会遇到,以前也没怎么去理它,今天有空学习了一下这方面的知识,于是便将本人学到的SpringMVC中单文件与多文件上传这部分知识做下笔记。


二、多文件上传

1、页面

这里以一个简单的表单提交为例子,文件上传需要将表单的提交方法设置为post,将enctype的值设置为"multipart/form-data"。

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <base href="<%=basePath%>">
    <title>Insert title here</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
</head>
<body>
    <form action="test/upload1" method="post" enctype="multipart/form-data">
        file 1 : <input type="file" name="imgs"><br />
        file 2 : <input type="file" name="imgs"><br />
        file 3 : <input type="file" name="imgs"><br />

        <input type="submit" name="提交">
    </form>
</body>
</html>

2、控制器

在Controller的处理方法中,使用MultipartFile对象作为参数接收前端上传过来的文件,具体说明请看代码注释。

/**
 * @author Ray
 * @date 2018/4/22 0021
 */
@Controller
@RequestMapping(value = "/test")
public class FileUploadController {

    @RequestMapping(value = "/filesupload")
    public String fileupload(){
        return "filesupload";
    }

    /**
     * 多文件上传
     */
    @RequestMapping(value = "/upload1", method = RequestMethod.POST)
    // 这里的MultipartFile对象变量名跟表单中的file类型的input标签的name相同,
    // 所以框架会自动用MultipartFile对象来接收上传过来的文件,
    // 当然也可以使用@RequestParam("img")指定其对应的参数名称
    public String upload(@RequestParam MultipartFile[] imgs, HttpSession session) throws IOException {
        for (MultipartFile img : imgs){
            // 如果没有文件上传,MultipartFile也不会为null,可以通过调用getSize()方法获取文件的大小来判断是否有上传文件
            if(img.getSize() > 0){
                //本地路径/test文件夹
                String path = "F:\\test\\";
                // 得到文件的原始名称,如:pig.png
                String fileName = img.getOriginalFilename();
                // 通过文件的原始名称,可以对上传文件类型做限制,如:只能上传jpg和png的图片文件
                if(fileName.endsWith("jpg") || fileName.endsWith("png")){
                    File file = new File(path, fileName);
                    img.transferTo(file);
                }
            }
        }
        return "success";
    }
}

3、测试


ok!


三、多种文件上传情景综合

当然,项目开发中,场景可能并不是这么简单,上述的多文件上传是一个个文件选择后一起上传(即多个name相同的input标签),那要是我项目中只要一个input标签就可以一次性多个文件呢?又或者一个页面中既要一个个选择的多文件上传,又要一次性选择的多文件上传,还要有单文件上传呢?没问题,MultipartFile[]通吃,代码也很easy,下面直接上代码。

1、页面

这里的 “一次选择多个文件的多文件上传” 只是在input标签中加上了multiple属性而已。

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <base href="<%=basePath%>">
    <title>Insert title here</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
</head>
<body>
    <form action="test/upload1" method="post" enctype="multipart/form-data">
        file 1 : <input type="file" name="imgs"><br />
        file 2 : <input type="file" name="imgs"><br />
        file 3 : <input type="file" name="imgs"><br />

        <input type="submit" name="提交">
    </form>

<br><br><hr>

    <form action="test/upload2" method="post" enctype="multipart/form-data">
        一次选择多个文件的多文件上传 : <br />
        <input type="file" name="imgs1" multiple><br /> <br />

        一次选择一个文件的多文件上传 : <br />
        <input type="file" name="imgs2"><br />
        <input type="file" name="imgs2"><br /><br />

        单文件上传 : <br />
        <input type="file" name="imgs3"><br /><br />

        <input type="submit" name="提交">
    </form>
</body>
</html>

2、控制器

控制器中的处理方法使用MultipartFile[]数组作为接收参数,并不能直接使用,需要校正参数,具体说明请看代码注释。

/**
 * @author Ray
 * @date 2018/4/22 0021
 */
@Controller
@RequestMapping(value = "/test")
public class FileUploadController {

    @RequestMapping(value = "/filesupload")
    public String fileupload(){
        return "filesupload";
    }

    /**
     * 多文件上传
     */
    @RequestMapping(value = "/upload1", method = RequestMethod.POST)
    // 这里的MultipartFile对象变量名跟表单中的file类型的input标签的name相同,
    // 所以框架会自动用MultipartFile对象来接收上传过来的文件,
    // 当然也可以使用@RequestParam("img")指定其对应的参数名称
    public String upload(@RequestParam MultipartFile[] imgs, HttpSession session) throws IOException {
        for (MultipartFile img : imgs){
            // 如果没有文件上传,MultipartFile也不会为null,可以通过调用getSize()方法获取文件的大小来判断是否有上传文件
            if(img.getSize() > 0){
                //本地路径/test文件夹
                String path = "F:\\test\\";
                // 得到文件的原始名称,如:pig.png
                String fileName = img.getOriginalFilename();
                // 通过文件的原始名称,可以对上传文件类型做限制,如:只能上传jpg和png的图片文件
                if(fileName.endsWith("jpg") || fileName.endsWith("png")){
                    File file = new File(path, fileName);
                    img.transferTo(file);
                }
            }
        }
        return "success";
    }

    /**
     * 多种文件上传情景综合
     */
    @RequestMapping(value = "/upload2", method = RequestMethod.POST)
    public String upload2(@RequestParam MultipartFile[] imgs1,
                          @RequestParam MultipartFile[] imgs2,
                          @RequestParam MultipartFile[] imgs3,
                          HttpSession session) throws IOException {
        String path = "F:\\test\\"; //本地路径/test
        for(MultipartFile img : imgs1){
            uploadFile(path, img);
        }
        for (MultipartFile img : imgs2) {
            uploadFile(path, img);
        }
        for (MultipartFile img : imgs3) {
            uploadFile(path, img);
        }
        return "success";
    }

    private void uploadFile(String path, MultipartFile img) throws IOException {
        if(img.getSize() > 0){
            String fileName = img.getOriginalFilename();
            if(fileName.endsWith("jpg") || fileName.endsWith("png")){
                File file = new File(path, fileName);
                img.transferTo(file);
            }
        }
    }
}

MultipartFile[]就是如此强大,不管单个多个,逻辑处理一样,所以建议在项目开发中使用MultipartFile[]作为文件的接收参数。

3、测试




四、拓展

1、MultipartFile类常用的一些方法:

String getContentType()//获取文件MIME类型
InputStream getInputStream()//获取文件流
String getName() //获取表单中文件组件的名字
String getOriginalFilename() //获取上传文件的原名
long getSize()  //获取文件的字节大小,单位byte
boolean isEmpty() //是否为空
void transferTo(File dest)

2、CommonsMultipartResolver的属性解析

defaultEncoding:表示用来解析request请求的默认编码格式,当没有指定的时候根据Servlet规范会使用默认值ISO-8859-1。当request自己指明了它的编码格式的时候就会忽略这里指定的defaultEncoding。
uploadTempDir:设置上传文件时的临时目录,默认是Servlet容器的临时目录。
maxUploadSize:设置允许上传的总的最大文件大小,以字节为单位计算。当设为-1时表示无限制,默认是-1。
maxUploadSizePerFile:跟maxUploadSize差不多,不过maxUploadSizePerFile是限制每个上传文件的大小,而maxUploadSize是限制总的上传文件大小。
maxInMemorySize:设置在文件上传时允许写到内存中的最大值,以字节为单位计算,默认是10240。
resolveLazily:为true时,启用推迟文件解析,以便在UploadAction中捕获文件大小异常。


五、注意

在开发过程中,建议把配置文件中的异常解析器(SimpleMappingExceptionResolver)先注释掉,方便我们查看错误。有时候上传出错,是因为我们在配置文件中限制了上传文件的大小,你可以不加这个限制,但个人建议这个限制最好还是加上,具体文件大小限制请根据公司项目情况而定。SpringMVC中使用MultipartFile接收上传文件需要依赖两个jar包,分别是:commons-fileupload-1.3.1.jar、commons-io-2.4.jar。


作者:CSDN_LQR
链接:https://www.jianshu.com/p/96cc3e869646

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值