软件编程
位置:首页>> 软件编程>> java编程>> SpringMVC实现文件上传与下载、 * 、异常处理器等功能

SpringMVC实现文件上传与下载、 * 、异常处理器等功能

作者:gonghr  发布时间:2023-07-21 19:18:44 

标签:springmvc,上传, ,
目录
  • 文件下载

  • 文件上传

  • *

    • * 的配置

    • 多个 * 的执行顺序

  • 异常处理器

    • 基于配置的异常处理

    • 基于注解的异常处理

  • 总结

    文件下载

    使用ResponseEntity实现下载文件的功能

    index.html


    <!DOCTYPE html>
    <html lang="en" xmlns:th="http:www.thymeleaf.org">
    <head>
       <meta charset="UTF-8">
       <title>首页</title>
    </head>
    <body>
    <a th:href="@{/testDown}" rel="external nofollow" >点击下载</a>
    </body>
    </html>

    控制器


    @RequestMapping("/testDown")
    public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
       //获取ServletContext对象
       ServletContext servletContext = session.getServletContext();

    //获取服务器中文件的真实路径
       String realPath = servletContext.getRealPath("/static/img/1.jpg");

    //创建输入流
       InputStream is = new FileInputStream(realPath);

    //创建字节数组
       byte[] bytes = new byte[is.available()];

    //将流读到字节数组中
       is.read(bytes);

    //创建HttpHeaders对象设置响应头信息
       MultiValueMap<String, String> headers = new HttpHeaders();

    //设置要下载方式以及下载文件的名字
       headers.add("Content-Disposition", "attachment;filename=1.jpg");

    //设置响应状态码
       HttpStatus statusCode = HttpStatus.OK;

    //创建ResponseEntity对象
       ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);

    //关闭输入流
       is.close();

    return responseEntity;
    }

    注意:如果报500错误,可能是项目中无法找到静态资源文件,需要对项目重新打包。

    文件上传

    文件上传要求form表单的请求方式必须为post,并且添加属性enctype="multipart/form-data"以二进制方式上传

    SpringMVC中将上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息

    上传步骤:

    添加依赖


    <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
    <dependency>
       <groupId>commons-fileupload</groupId>
       <artifactId>commons-fileupload</artifactId>
       <version>1.3.1</version>
    </dependency>

    在SpringMVC的配置文件springMVC.xml中添加配置


    <!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
    <!--必须设置id属性,springMVC是根据id获取,且id必须设置为multipartResolver-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

    index.html


    <form method="post" th:action="@{/testUp}" enctype="multipart/form-data">
       <input type="file" name="photo">
       <input type="submit" value="上传">
    </form>

    控制器


    @RequestMapping("/testUp")

    //MultipartFile的形参名必须与index.html中的file标签的name一致
    public String testUp(MultipartFile photo, HttpSession session) throws IOException {
       //获取上传的文件的文件名
       String fileName = photo.getOriginalFilename();

    //处理文件重名问题
       String hzName = fileName.substring(fileName.lastIndexOf("."));
       fileName = UUID.randomUUID().toString() + hzName;

    //获取服务器中photo目录的路径
       ServletContext servletContext = session.getServletContext();
       String photoPath = servletContext.getRealPath("photo");
       File file = new File(photoPath);
       if(!file.exists()){
           file.mkdir();
       }
       String finalPath = photoPath + File.separator + fileName;

    //实现上传功能
       photo.transferTo(new File(finalPath));
       return "success";
    }

    *

    * 的配置

    SpringMVC中的 * 用于拦截控制器方法的执行

    SpringMVC中的 * 需要实现HandlerInterceptor接口

    HandlerInterceptor源码


    public interface HandlerInterceptor {
       default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
           return true;
       }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
       }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
       }
    }

    HandlerInterceptor接口有三个默认方法

    • preHandle:控制器方法执行之前执行preHandle(),其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法;返回false表示拦截,即不调用控制器方法

    • postHandle:控制器方法执行之后执行postHandle()

    • afterCompletion:处理完视图和模型数据,渲染视图完毕之后执行afterCompletion()

    控制器

    FirstInterceptor.java


    public class FirstInterceptor implements HandlerInterceptor {
       public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
           System.out.println("FirstInterceptor-->preHandle");
           return false;
       }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
           System.out.println("FirstInterceptor-->postHandle");
       }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
           System.out.println("FirstInterceptor-->afterCompletion");
       }
    }

    SpringMVC的 * 必须在SpringMVC的配置文件中进行配置:

    方式一


       <mvc:interceptors>
           <bean class="com.gonghr.springmvc.interceptors.FirstInterceptor"></bean>
       </mvc:interceptors>

    输出:

    FirstInterceptor-->preHandle

    方式二


       <mvc:interceptors>
           <ref bean="firstInterceptor"></ref>
       </mvc:interceptors>

    注意提前开启注解扫描,并把 * 放入Ioc容器

    输出:

    FirstInterceptor-->preHandle

    注意:以上两种配置方式都是对DispatcherServlet所处理的所有的请求进行拦截。

    方式三


       <mvc:interceptors>
           <mvc:interceptor>
               <mvc:mapping path="/**"/>  <!--拦截所有请求-->
               <mvc:exclude-mapping path="/"/>  <!--不拦截主页-->
               <ref bean="firstInterceptor"></ref>
           </mvc:interceptor>
       </mvc:interceptors>

    SpringMVC实现文件上传与下载、 * 、异常处理器等功能

    可以进入首页

    SpringMVC实现文件上传与下载、 * 、异常处理器等功能

    发送任意请求都会被拦截

    输出:

    FirstInterceptor-->preHandle

    以上配置方式可以通过ref或bean标签设置 * ,通过mvc:mapping设置需要拦截的请求,通过mvc:exclude-mapping设置需要排除的请求,即不需要拦截的请求

    /**:拦截所有请求

    /*:拦截一级目录的请求

    多个 * 的执行顺序

    第一个 *


    @Component
    public class FirstInterceptor implements HandlerInterceptor {
       public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
           System.out.println("FirstInterceptor-->preHandle");
           return true;
       }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
           System.out.println("FirstInterceptor-->postHandle");
       }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
           System.out.println("FirstInterceptor-->afterCompletion");
       }
    }

    第二个 *


    @Component
    public class SecondInterceptor implements HandlerInterceptor {
       public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
           System.out.println("SecondInterceptor-->preHandle");
           return true;
       }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
           System.out.println("SecondInterceptor-->postHandle");
       }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
           System.out.println("SecondInterceptor-->afterCompletion");
       }
    }

    两个 * 都设置为对任意请求放行。

    输出:

    FirstInterceptor-->preHandle
    SecondInterceptor-->preHandle
    SecondInterceptor-->postHandle
    FirstInterceptor-->postHandle
    SecondInterceptor-->afterCompletion
    FirstInterceptor-->afterCompletion

    • 若每个 * 的preHandle()都返回true

    此时多个 * 的执行顺序和 * 在SpringMVC的配置文件的配置顺序有关:

    preHandle()会按照配置的顺序执行,而postHandle()和afterCompletion()会按照配置的反序执行

    如果设置第一个 * 对所有请求放行,第二个 * 对所有请求拦截。

    第一个 *


    @Component
    public class FirstInterceptor implements HandlerInterceptor {
       public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
           System.out.println("FirstInterceptor-->preHandle");
           return true;
       }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
           System.out.println("FirstInterceptor-->postHandle");
       }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
           System.out.println("FirstInterceptor-->afterCompletion");
       }
    }

    第二个 *


    @Component
    public class SecondInterceptor implements HandlerInterceptor {
       public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
           System.out.println("SecondInterceptor-->preHandle");
           return false;
       }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
           System.out.println("SecondInterceptor-->postHandle");
       }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
           System.out.println("SecondInterceptor-->afterCompletion");
       }
    }

    输出:

    FirstInterceptor-->preHandle
    SecondInterceptor-->preHandle
    FirstInterceptor-->afterCompletion

    • 若某个 * 的preHandle()返回了false

    preHandle()返回false和它之前的 * 的preHandle()都会执行,postHandle()都不执行,返回false的 * 之前的 * 的afterCompletion()会执行

    异常处理器

    基于配置的异常处理

    SpringMVC提供了一个处理控制器方法执行过程中所出现的异常的接口:HandlerExceptionResolver

    HandlerExceptionResolver接口的实现类有:DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver

    SpringMVC提供了自定义的异常处理器SimpleMappingExceptionResolver,使用方式:


    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
       <property name="exceptionMappings">
           <props>
           <!--
           properties的键表示处理器方法执行过程中出现的异常
           properties的值表示若出现指定异常时,设置一个新的视图名称,跳转到指定页面
           -->
               <prop key="java.lang.ArithmeticException">error</prop>
           </props>
       </property>
       <!--
       exceptionAttribute属性设置一个属性名,将出现的异常信息在请求域中进行共享
       -->
       <property name="exceptionAttribute" value="ex"></property>
    </bean>

    error.html


    出现错误
    <p th:text="${ex}"></p>

    index.html


    <a th:href="@{/testException}">测试异常处理</a>

    SpringMVC实现文件上传与下载、 * 、异常处理器等功能

    基于注解的异常处理


    //@ControllerAdvice将当前类标识为异常处理的组件
    @ControllerAdvice
    public class ExceptionController {

    //@ExceptionHandler用于设置所标识方法处理的异常
       @ExceptionHandler(value = {ArithmeticException.class,NullPointerException.class})
       //ex表示当前请求处理中出现的异常对象
       public String handleArithmeticException(Exception ex, Model model){
           model.addAttribute("ex", ex);
           return "error";
       }

    }

    SpringMVC实现文件上传与下载、 * 、异常处理器等功能

    来源:https://www.cnblogs.com/gonghr/p/15235253.html

    0
    投稿

    猜你喜欢

    手机版 软件编程 asp之家 www.aspxhome.com