SpringMVC: Reference - SpringMVC single file upload and multiple file upload

SpringMVC: Reference - SpringMVC single file upload and multiple file upload

--------720 Zhang Senpeng

1. Brief introduction

In a javaWeb project, the file upload function is almost indispensable. I often encounter it in project development. I didn't pay much attention to it before. Today I have time to learn about this knowledge, so I will learn it myself. Take notes on the knowledge of single file and multi-file upload in SpringMVC.

2. Single file upload

1. Page

Here is an example of a simple form submission. To upload a file, set the submit method of the form to post and set the value of enctype to "multipart/form-data".

<form action="${pageContext.request.contextPath}/test/upload.do" method="post" enctype="multipart/form-data">
    <input type="file" name="img"><br /> 
    <input type="submit" name="提交">
</form>2.控制器

In the processing method of the Controller, the MultipartFile object is used as a parameter to receive the file uploaded by the front-end. For details, please refer to the code comments.

@Controller
@RequestMapping("/test")
public class MyController {

    @RequestMapping(value = "/upload.do", method = RequestMethod.POST)
    // 这里的MultipartFile对象变量名跟表单中的file类型的input标签的name相同,//所以框架会自动用MultipartFile对象来接收上传过来的文件,当然也可以使用@RequestParam("img")指定其对应的参数名称
    public String upload(MultipartFile img, HttpSession session)
            throws Exception {
        // 如果没有文件上传,MultipartFile也不会为null,可以通过调用getSize()方法获取文件的大小来判断是否有上传文件
        if (img.getSize() > 0) {
            // 得到项目在服务器的真实根路径,如:/home/tomcat/webapp/项目名/images
            String path = session.getServletContext().getRealPath("images");
            // 得到文件的原始名称,如:美女.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.jsp";
            }
        }
        return "/error.jsp";
    }
}3、springmvc.xml配置

To use the MultipartFile object to receive the files uploaded from the front end, you also need to configure the following in the springmvc configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    ...

    <!-- 注意:CommonsMultipartResolver的id是固定不变的,一定是multipartResolver,不可修改 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 如果上传后出现文件名中文乱码可以使用该属性解决 -->
        <property name="defaultEncoding" value="utf-8"/>
        <!-- 单位是字节,不设置默认不限制总的上传文件大小,这里设置总的上传文件大小不超过1M(1*1024*1024) -->
        <property name="maxUploadSize" value="1048576"/>
        <!-- 跟maxUploadSize差不多,不过maxUploadSizePerFile是限制每个上传文件的大小,//而maxUploadSize是限制总的上传文件大小 -->
        <property name="maxUploadSizePerFile" value="1048576"/>
    </bean>

    <!-- 设置一个简单的异常解析器,当文件上传超过大小限制时跳转 -->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="defaultErrorView" value="/error.jsp"/>
    </bean>
</beans>

The attribute value configuration under CommonsMultipartResolver in the above configuration file is not necessary, you can also not write all of them. Here you can achieve a single file upload, let's take a look at the multi-file upload.

3. Uploading multiple files

In fact, multi-file upload is also very simple. Single-file upload is to use the MultipartFile object as a parameter in the processing method of the Controller to receive the file uploaded from the front-end, while multi-file upload is received using the MultipartFile object array.

1. Page

There are several input tags of file type with the same name value in this page, and other pages with single file upload are no different.

<form action="${pageContext.request.contextPath}/test/upload.do" 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>2、控制器

The processing method in the controller uses the MultipartFile[] array as the receiving parameter, which cannot be used directly. The parameters need to be corrected. For details, please refer to the code comments.

@Controller
@RequestMapping("/test")
public class MyController {

    @RequestMapping(value = "/upload.do", method = RequestMethod.POST)
    // 这里的MultipartFile[] imgs表示前端页面上传过来的多个文件,imgs对应页面中多个file类型的input标签的name,          //  但框架只会将一个文件封装进一个MultipartFile对象,    // 并不会将多个文件封装进一个MultipartFile[]数组,//直接使用会报[Lorg.springframework.web.multipart.MultipartFile;.<init>()错误,    // 所以需要用@RequestParam校正参数(参数名与MultipartFile对象名一致),//当然也可以这么写:@RequestParam("imgs") MultipartFile[] files。
    public String upload(@RequestParam MultipartFile[] imgs, HttpSession session)
            throws Exception {
        for (MultipartFile img : imgs) {
            if (img.getSize() > 0) {
                String path = session.getServletContext().getRealPath("images");
                String fileName = img.getOriginalFilename();
                if (fileName.endsWith("jpg") || fileName.endsWith("png")) {
                    File file = new File(path, fileName);
                    img.transferTo(file);
                }
            }
        }
        return "/success.jsp";
    }
}

Similarly, using the MultipartFile array to receive multiple files uploaded from the front end also needs to be configured in the springmvc configuration file. The specific configuration is the same as the springmvc.xml configuration for the above single file upload, just copy it directly. In this way, multiple file uploads can be performed.

4. Synthesis of various file upload scenarios

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

1、页面

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

<form action="${pageContext.request.contextPath}/test/upload.do" 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>2、控制器
@Controller
@RequestMapping("/test")
public class MyController {

    @RequestMapping(value = "/upload.do", method = RequestMethod.POST)
    public String upload(@RequestParam MultipartFile[] imgs1,@RequestParam MultipartFile[] imgs2,@RequestParam MultipartFile[] imgs3, HttpSession session)
            throws Exception {
        String path = session.getServletContext().getRealPath("images");
        for (MultipartFile img : imgs1) {
            uploadFile(path, img);
        }
        for (MultipartFile img : imgs2) {
            uploadFile(path, img);
        }
        for (MultipartFile img : imgs3) {
            uploadFile(path, img);
        }
        return "/success.jsp";
    }

    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[]作为文件的接收参数。

五、拓展

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324628852&siteId=291194637