深入SpringMVC-文件上传

本文转载此博客,感谢作者的用心书写

单文件上传

页面

文件上传需要将表单的提交方法设置为post,将enctype的值设置为"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>
控制器

在Controller的处理方法中,使用MultipartFile对象作为参数接收前端上传过来的文件

@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);
                //将上传的文件存储到File对应路径下
                img.transferTo(file);
                return "/success.jsp";
            }
        }
        return "/error.jsp";
    }
}
springmvc.xml配置

使用MultipartFile对象接收前端上传过来的文件,还需要在springmvc的配置文件中进行如下配置:

<!-- 注意: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>

多文件上传

单文件上传是在Controller的处理方法中使用MultipartFile对象作为参数接收前端上传过来的文件,而多文件上传则使用MultipartFile对象数组来接收

页面
<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>
控制器

控制器中的处理方法使用MultipartFile[]数组作为接收参数,并不能直接使用,需要校正参数

@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";
    }
}

使用MultipartFile数组接收前端上传过来的多个文件,也需要在springmvc的配置文件进行配置,具体配置与上述单文件上传的springmvc.xml配置相同

多种文件上传情景综合

当然,项目开发中,场景可能并不是这么简单,上述的多文件上传是一个个文件选择后一起上传(即多个name相同的input标签),那要是我项目中只要一个input标签就可以一次性多个文件呢?又或者一个页面中既要一个个选择的多文件上传,又要一次性选择的多文件上传,还要有单文件上传呢?
这些情景都可以通过MultipartFile[]实现。

页面

这里的 “一次选择多个文件的多文件上传” 只是在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>
控制器
@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类常用的一些方法

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

CommonsMultipartResolver的属性解析

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

猜你喜欢

转载自blog.csdn.net/weixin_40288381/article/details/88927421
今日推荐