• 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     }
  • 相关阅读:
    SSDB安装配置记录
    Ubuntu上通过nginx部署Django笔记
    PyCharm创建virtualenv方法
    Python3--列表生成式
    K最近邻算法项目实战
    K最近邻算法
    人工智能之机器学习
    C#把汉字转换成16进制(HEX)并向串口发送数据
    Ubuntu-18.04.2系统 Nginx+uWSGI+Django 部署生产环境
    HTTP响应状态码说明
  • 原文地址:https://www.cnblogs.com/57rongjielong/p/7828064.html
Copyright © 2020-2023  润新知