SpringMVC文件上传和自定义异常处理解析器

SpringMVC文件上传和自定义异常处理解析器

SpringMVC文件上传基于commons-fileupload组件,所以我们要到如commons-fileupload相关的包

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>
  1. 实现简单文件上传

    1. 在SpringMVC中配置CommonsMultipartResolver

      • <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        </bean>
        
    2. 编写jsp页面

      • <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
        <html>
        <head>
            <title>文件上传</title>
        </head>
        <body>
        <form action="${pageContext.request.contextPath}/file/upload" method="post" enctype="multipart/form-data">
            文件:<input type="file" name="file" /><br />
            <input type="submit" value="上传" />
        </form>
        </body>
        </html>
        
    3. 编写Controller代码

      • package com.fxyh.springmvc.web.controller;
        
        import org.springframework.stereotype.Controller;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.PostMapping;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.ResponseBody;
        import org.springframework.web.multipart.MultipartFile;
        
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpSession;
        import java.io.File;
        import java.io.IOException;
        
        @Controller
        @RequestMapping("/file")
        public class FileController {
        
            @GetMapping("/upload")
            public String upload() {
                return "file/upload";
            }
        
            @PostMapping("/upload")
            public Object upload(MultipartFile file, HttpServletRequest request) {
                HttpSession session = request.getSession();
                String uploadPath = session.getServletContext().getRealPath("/files");
                File uploadFile = new File(uploadPath);
                if (!uploadFile.exists()) {
                    uploadFile.mkdirs();
                }
                String filename = file.getOriginalFilename();
                try {
                    file.transferTo(new File(uploadFile, filename));
                    request.setAttribute("msg", filename + "上传成功");
                } catch (IOException e) {
                    e.printStackTrace();
                    request.setAttribute("msg", filename + "上传失败");
        
                }
                return "file/success";
            }
        }
        
    4. 这里就实现了一个简单的单个文件上传,这个文件会上传到webapp目录下的files文件夹中。

  2. 问题

    1. 文件名为中文时乱码问题

      1. 在CommonsMultipartResolver中配置defaultEncoding属性

        • <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
             <property name="defaultEncoding" value="UTF-8"/>
          </bean>
          
      2. 在web.xml中配置过滤器

        • <filter>
           <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
           <url-pattern>/*</url-pattern>
          </filter-mapping>
          
    2. 多文件上传怎么处理

      • 在原来单个的基础上改了一些

        • 多文件上传
          <form action="${pageContext.request.contextPath}/file/uploads" method="post" enctype="multipart/form-data">
            文件1:<input type="file" name="file" /><br />
            文件2:<input type="file" name="file" /><br />
            文件3:<input type="file" name="file" /><br />
            <input type="submit" value="上传" />
          </form>
          
        • @PostMapping("/uploads")
          public Object uploads(MultipartFile[] file, HttpServletRequest request) {
            HttpSession session = request.getSession();
            String uploadPath = session.getServletContext().getRealPath("/files");
            File uploadFile = new File(uploadPath);
            if (!uploadFile.exists()) {
                uploadFile.mkdirs();
            }
            StringBuffer sb = new StringBuffer();
            for (MultipartFile multipartFile : file) {
                String filename = multipartFile.getOriginalFilename();
                try {
                    multipartFile.transferTo(new File(uploadFile, filename));
                    sb.append(filename).append("上传成功,");
                } catch (IOException e) {
                    e.printStackTrace();
                    sb.append(filename).append("上传失败,");
                }
            }
            request.setAttribute("msg", sb.toString());
            return "file/success";
          }
          
      • 多文件上传时在Controller中使用数组进行接收,然后循环这个数组进行上传。

    3. 文件名冲突怎么办

      • 文件上传一般会进行重命名,使用UUID进行重命名
    4. 文件大小怎么控制

      • spring.upload.max_size_per_file=2097152
        spring.upload.max_size_total=10485760
        spring.upload.allow_upload_file_type=png,jpg
        
      • 在springmvc中引入这个properties文件

        • <!--<context:property-placeholder location="classpath*:upload.properties"/>-->
          <bean id="placeholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <array>
                    <value>classpath*:upload.properties</value>
                </array>
            </property>
          </bean>
          
        • 这两种方法都可以使用

      • @Value("${spring.upload.max_size_per_file}")
        private Long maxUploadPerFile;
        
        @Value("${spring.upload.max_size_total}")
        private Long maxSizeTotal;
        @PostMapping("/uploads")
        public Object uploads(MultipartFile[] file, HttpServletRequest request) {
          HttpSession session = request.getSession();
          String uploadPath = session.getServletContext().getRealPath("/files");
          File uploadFile = new File(uploadPath);
          if (!uploadFile.exists()) {
            uploadFile.mkdirs();
          }
          StringBuffer sb = new StringBuffer();
          for (MultipartFile multipartFile : file) {
            String filename = multipartFile.getOriginalFilename();
            String extension = FilenameUtils.getExtension(filename);
            if (allowUploadFileType.indexOf(extension) < 0){
              throw new CustomException("上传文件的类型不允许,只能上传" + allowUploadFileType + "文件");
            }
            long size = multipartFile.getSize();
            if (size > maxUploadPerFile) {
              throw new CustomException("文件大小超过了" + maxUploadPerFile / 1024 / 1024 + "MB");
            }
            try {
              multipartFile.transferTo(new File(uploadFile, filename));
              sb.append(filename).append("上传成功,");
            } catch (IOException e) {
              e.printStackTrace();
              sb.append(filename).append("上传失败,");
            }
          }
          request.setAttribute("msg", sb.toString());
          return "file/success";
        }
        
    5. 文件类型怎么过滤

      • 例子见文件大小过滤
    6. 上传目录怎么打散

      • 例如根据时间来打散,每天的一个目录或者一天一个目录,然后目录里在分小时,时里面再分分钟
  3. 自定义异常处理解析器

    • 定义异常

      • package com.fxyh.springmvc.common;
        
        public class CustomException extends RuntimeException {
           private static final long serialVersionUID = 4902874743631868805L;
        
           private String message;
        
           public CustomException() {
           }
        
           public CustomException(String message) {
               super(message);
               this.message = message;
           }
        }
        
    • 定义解析器

      • package com.fxyh.springmvc.common;
        
        import org.springframework.web.servlet.HandlerExceptionResolver;
        import org.springframework.web.servlet.ModelAndView;
        
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        
        public class CustomHandlerExceptionResolver implements HandlerExceptionResolver {
        
           @Override
           public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
               ModelAndView modelAndView = new ModelAndView();
               if (ex != null) {
                   if (ex instanceof CustomException) {
                       CustomException customException = (CustomException) ex;
                       String message = customException.getMessage();
                       modelAndView.addObject("error", message);
                       modelAndView.setViewName("common/error");
                   }
               }
               return modelAndView;
           }
        
        }
        
    • 把这个解析器注册成一个组件

      • 在类上使用@Component注解,或者把这个配置在xml中

        • <bean id="customHandlerExceptionResolver" class="com.fxyh.springmvc.common.CustomHandlerExceptionResolver"/>
          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值