SpringMVC文件上传

1.spring提供了CommonsMultipartResolver解析器,用于实现文件上传功能

2.pom.xml文件中添加依赖包 commons-fileupload-1.3.1、commons-io-2.2、commons-logging-1.0.4

3.jsp页面(注意:以下是基于spring-mvc已经配置好的情况下使用的)

在form表单中,需要设置method="post",还要设置enctype="multipart/form-data"

    <!-- 单文件上传 -->
    <form action="${basePath }/upload/file1" method="post" enctype="multipart/form-data">
        <input type="file" name="file1" >
        <input type="submit" value="上传">
    </form>

在后台Controller中实现上传

 1     /**
 2      * 实现图片上传,并且跳转到一个视图页面进行显示
 3      * 
 4      * 1.MultipartFile:springmvc会自动的通过文件上传解析器,将表单的文件等信息转成MultipartFile接口类型子类对象
 5      * 2.方法中的参数名file1需要与表单中的文件上传组件的name一致
 6      * @return
 7      */
 8 
 9     @RequestMapping("/file1")
10     public String fileUpload1(MultipartFile file1,HttpServletRequest request,HttpServletResponse response){
11         //获取上传的文件原名
12         String filename=file1.getOriginalFilename();
13         System.out.println(filename);
14         //获取服务器真实物理路径  
15         String realPath = request.getServletContext().getRealPath("file");
16         System.out.println("当前真实物理路径为:"+realPath);
17         File targetFile = new File(realPath, filename);
18         response.setContentType("text/html;charset=utf-8");
19         if(!targetFile.exists()){
20             targetFile.mkdirs();//递归创建当前文件的父文件夹
21         }
22         try {
23             file1.transferTo(targetFile);
24             String url=request.getContextPath()+File.separator+"file"+File.separator+filename;
25             request.setAttribute("url", url);
26         } catch (IllegalStateException | IOException e) {
27             e.printStackTrace();
28         }
29         return "fileView";
30     }

jsp页面显示上传的图片

<body>
    fileView.jsp ${url }
    <img alt="tupian" src="${url }">
</body>

配置文件上传解析器multipartResolver(由于设置了Restful,需要指定静态资源匹配

    <!-- 配置上传的文件的静态资源访问映射 -->
    <mvc:resources location="/file/" mapping="/file/**"></mvc:resources>

    <!-- 配置文件上传解析器multipartResolver 
        必须按照该固定bean的id值来设置,否则不生效
    -->
    <bean id="multipartResolver" 
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置总上传文件大小    单位是字节 -->
        <!-- <property name="maxUploadSize" value="104857"></property>
        设置延迟解析为true 才能让自定义异常生效
        <property name="resolveLazily" value="true"></property> -->
    </bean>

中文文件名上传引发的一些乱码问题!!!

A.中文名称文件使用post方式上传

  使用spring提供的编码过滤器可以解决中文乱码问题(前提:项目统一编码)

 <!-- 通过spring提供的过滤器解决乱码问题 -->
 <filter>
     <filter-name>encodingFilter</filter-name>
     <filter-class>
         org.springframework.web.filter.CharacterEncodingFilter
     </filter-class>
     <init-param>
         <param-name>encoding</param-name>
         <param-value>UTF-8</param-value>
     </init-param>
 </filter>
 <filter-mapping>
     <filter-name>encodingFilter</filter-name>
     <url-pattern>/*</url-pattern>
 </filter-mapping>

B.在html/jsp页面中,引用了带汉字的图片,如:<img src="/目录/子目录/图片名字.jpg" />,如果没有在tomcat配置URIEncoding,则无法显示。

  jsp页面加载时,加载中文名的静态资源,出现乱码,自然就获取不到请求资源,无法加载了,jsp页面是没有乱码的。但是后台配置了编码过滤器的,为什么还会乱码呢?

  jsp页面加载时,会加载src引入的静态资源,请求方式是GET,而GET方式的请求会经过tomcat,在没有配置tomcat解析请求的解码方式的情况下,默认是ISO-8859-1,然后再经过后台配置的编码过滤器解析时,由于请求已经经过tomcat的解析,编码过滤器再次解析请求地址时,就会出现中文乱码。(编码过滤器对Get提交方式无效

4. 限制文件格式

CommonsMultipartResolver类在spring-web包下:
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
<form action="/Web1/upload.action" method="post" enctype="multipart/form-data">
    <input type="file" name="myFile">
    <input type="submit" value="上传">
</form>
${msg }
 1     @RequestMapping("/file.action")
 2     public String file() {
 3         return "file";
 4     }
 5 
 6     @RequestMapping("/upload.action")
 7     public String upload(MultipartFile myFile, HttpServletRequest req) {
 8         String filename = myFile.getOriginalFilename();
 9         //限制只能是.png格式
10         if (!filename.toLowerCase().endsWith(".png")) {
11             req.setAttribute("msg", "格式不符合要求!必须是png格式!");
12         } else {
13             String realPath = req.getServletContext().getRealPath("/file");
14             File file = new File(realPath, filename);
15             if (!file.exists()) {
16                 file.mkdirs();
17             }
18             try {
19                 myFile.transferTo(file);
20                 req.setAttribute("msg", filename);
21             } catch (IllegalStateException e) {
22                 e.printStackTrace();
23             } catch (IOException e) {
24                 e.printStackTrace();
25             }
26 
27         }
28         return "file";
29     }

5. 多文件上传

由于spring框架没有将表单参数封装到myFiles对象上,所以要通过@RequestParam方式指定表单传递的参数封装到myFiles对象上

<form action="/Web1/upload.action" method="post" enctype="multipart/form-data">
    <input type="file" name="myFiles">
    <input type="file" name="myFiles">
    <input type="submit" value="上传">
</form>
 1     /**
 2      * 多文件上传
 3      * 1.表单上放多个file类型的input,并且name值一样
 4      * 2.MultipartFile[]类型接收  
 5      * 3.@RequestParam("myFiles")  :myFiles为页面提交的name值
 6      */
 7     @RequestMapping("/upload.action")
 8     public String upload(@RequestParam("myFiles") MultipartFile[] myFiles, HttpServletRequest req) {
 9         
10         for (MultipartFile myFile : myFiles) {
11             String filename = myFile.getOriginalFilename();
12 
13             String realPath = req.getServletContext().getRealPath("/file");
14             File file = new File(realPath, filename);
15             if (!file.exists()) {
16                 file.mkdirs();
17             }
18             try {
19                 myFile.transferTo(file);
20             } catch (IllegalStateException e) {
21                 e.printStackTrace();
22             } catch (IOException e) {
23                 e.printStackTrace();
24             }
25         }
26         return "file";
27     }

 6.限制文件上传数据大小

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设置总上传文件大小    单位是字节 -->
        <property name="maxUploadSize" value="1024000"></property>
    </bean>

这样设置的话,若总上传文件大小大于1M,控制台仍然会显示抛出异常,不会影响功能实现,但阻碍了开发者的判断:

严重: Servlet.service() for servlet [springmvc] in context with path [/Web1] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size of 1024000 bytes exceeded; nested exception is org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (3454760) exceeds the configured maximum (1024000)] with root cause
org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (3454760) exceeds the configured maximum (1024000)

解决:

解决方法不设置maxUploadSize,自定义拦截对文件的大小进行判断

 1 package com.rong.interceptor;
 2 
 3 import javax.servlet.http.HttpServletRequest;
 4 import javax.servlet.http.HttpServletResponse;
 5 
 6 import org.apache.commons.fileupload.servlet.ServletFileUpload;
 7 import org.apache.commons.fileupload.servlet.ServletRequestContext;
 8 import org.springframework.web.multipart.MaxUploadSizeExceededException;
 9 import org.springframework.web.servlet.HandlerInterceptor;
10 import org.springframework.web.servlet.ModelAndView;
11 /**
12  * 文件上传拦截器  解决文件超出大小后台异常问题
13  *
14  */
15 public class UploadInterceptor implements HandlerInterceptor {
16     private int maxUploadSize;
17     //属性依赖注入DI要使用set方法,必须提供
18     public void setMaxUploadSize(int maxUploadSize) {
19         this.maxUploadSize = maxUploadSize;
20     }
21 
22     @Override
23     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
24             throws Exception {
25             //判断是否有上传文件
26             if(request!=null&&ServletFileUpload.isMultipartContent(request)){
27                 ServletRequestContext context = new ServletRequestContext(request);
28                 long length = context.contentLength();
29                 //int length = request.getContentLength();
30                 System.out.println(length);
31                 if(length>this.maxUploadSize){
32                     throw new MaxUploadSizeExceededException(this.maxUploadSize);
33                 }
34             }
35         return true;
36     }
37 
38     @Override
39     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
40             ModelAndView modelAndView) throws Exception {
41     }
42 
43     @Override
44     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
45             throws Exception {
46     }
47 
48 }
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设置总上传文件大小    单位是字节 -->
        <!-- <property name="maxUploadSize" value="1024000"></property> -->
        <!-- 设置延迟解析为true 才能让自定义异常生效 -->
        <property name="resolveLazily" value="true"></property>
    </bean>
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/upload.action"/>
            <bean class="com.rong.interceptor.UploadInterceptor">
                <property name="maxUploadSize" value="1024000"></property>
            </bean>
        </mvc:interceptor>
    </mvc:interceptors>

 1     @RequestMapping("/upload.action")
 2     public String upload(@RequestParam("myFile") MultipartFile myFile, HttpServletRequest req) {
 3             String filename = myFile.getOriginalFilename();
 4             String realPath = req.getServletContext().getRealPath("/file");
 5             File file = new File(realPath, filename);
 6             if (!file.exists()) {
 7                 file.mkdirs();
 8             }
 9             try {
10                 myFile.transferTo(file);
11             } catch (IllegalStateException e) {
12                 e.printStackTrace();
13             } catch (IOException e) {
14                 e.printStackTrace();
15             }
16         return "file";
17     }
18 
19     /**
20      * 自定义异常处理   当发生超过最大上传数的时候,让程序返回上传页面,并提示
21      * 1.返回值类型ModelAndView  参数需要传入Exception或子类
22      * 2.增加ExceptionHandler
23      * 3.设置multipartResolver组件的属性<property name="resolveLazily" value="true"></property>
24      * @param e
25      * @return
26      */
27     @ExceptionHandler
28     public ModelAndView doException(Exception e){
29         Map<String,Object> map=new HashMap<>();
30         if(e instanceof MaxUploadSizeExceededException){
31             MaxUploadSizeExceededException exception=(MaxUploadSizeExceededException)e;
32             long maxUploadSize = exception.getMaxUploadSize();
33             map.put("msg", "文件过大!必须小于"+maxUploadSize+"字节!");
34         }else{
35             map.put("msg", "系统在忙!");
36         }
37         return new ModelAndView("file", map);
38     }
原文地址:https://www.cnblogs.com/57rongjielong/p/7828064.html