Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 5998|回复: 0

SpringMVC拦截器与异常处理

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-13 12:47:55 | 显示全部楼层 |阅读模式

     

    点击查看上一章

    在我们SpringMVC中也可以使用拦截器对用户的请求进行拦截,用户可以自定义拦截器来实现特定的功能。自定义拦截器必须要实现HandlerInterceptor接口

    package com.spring.mvc.interceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    /**
     * @author:SimpleWu
     * @to:拦截器执行流程:preHandle - 目标方法 - postHandle -渲染视图 - afterCompletion
     */
    public class MyInterceptor implements HandlerInterceptor{
        
        /**
         * 渲染视图之后被调用
         * 释放资源
         */
        @Override
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
                throws Exception {
            System.out.println("[MyInterceptor] afterCompletion");
        }
        /**
         * 该方法是在目标方法之后,渲染视图之前被调用
         * 可以对请求域中的参数或视图做出修改
         */
        @Override
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
                throws Exception {
            System.out.println("[MyInterceptor] postHandle");
        }
        /**
         * 该方法在目标方法前调用
         * 1)如果返回值为true则继续调用后续的拦截器和目标方法
         * 2)如果返回值为false则不会调用后续的拦截器和目标方法
         * 可以考虑做权限,日志。
         */
        @Override
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
            System.out.println("[MyInterceptor] preHandle : 目标方法之前被调用。");
            return true;
        }
    
    }

    然后我们需要在SpringMVC中配置拦截器。

    <mvc:interceptors>
            <!-- 配置自定义拦截器 -->
            <bean id="myInterceptor" class="com.spring.mvc.interceptor.MyInterceptor"/>
            <mvc:interceptor>
                <!-- 配置拦截器的作用路径 -->
                <mvc:mapping path="/user/*"/>
                <!-- 
                    配置拦截器不作用的路径
                    <mvc:exclude-mapping path=""/>
                 -->
                <bean class="com.spring.mvc.interceptor.UserInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>

    如果我们配置了作用的路径那么我们现在只有user/*后面的请求它才会被我们的拦截器给拦截。

    在我们拦截器中执行顺序:首先调用preHandler方法然后进入请求的业务方法之后出来的时候会先调用postHandler这个方法(业务方法前,视图渲染后),最后视图渲染之后调用拦截器的afterCompletion方法。

    如果我们有多个拦截器那么他会按照配置顺序执行preHandler,按逆方向执行postHandler与afterCompletion方法。

    假如我们有两个拦截器,在第一个拦截器的preHandler中返回false那么所有的方法都不会执行,如果我们在第二个拦截器返回false第一个拦截器还会多执行一个afterCompletion方法。

    SpringMVC异常处理

    在SpringMVC中异常的处理与Struts2有点类似。

    SpringMVC通过HandlerExceptionResolver处理程序异常,包括Handler映射,数据绑定以及目标方法执行时所发生的异常。

    SpringMVC中默认是没有加装载HandlerExceptionResolver,我们需要在SpringMVC.xml中配置

    <mvc:annotation-driven />

    我们可以在Controller类中定义一个局部(方法所在类)的异常处理的方法

    /**
         *    在这个方法中可以加入Exception类型的参数,该参数即对于发生的异常对象
         *    入参中不能传入map,若希望吧异常信息传到页面上需要使用ModelAndView作为返回值 
         */
        @ExceptionHandler({NullPointerException.class})
        public String handlerNullPointerException(Exception ex){
            System.out.println("异常 : " + ex);
            return "error";
        }

    这个方法他会针对这个类中的NullPointerException异常将他捕获,然后执行这个方法。如果我们希望在页面上显示异常信息的话我们只需要返回ModelAndView即可。

    除了这种局部异常我们还可以配置全局异常处理类,这个类需要使用注解@ControllerAdvice修饰。

    package com.spring.mvc.exceptionprocess;
    
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.servlet.ModelAndView;
    
    /**
     * @author SimpleWu
     * @ControllerAdvice:如果在当前Handler找不到当前方法出现的异常则将来这个注解标记的类中查找处理异常。
     * 意为定义一个全局异常
     */
    @ControllerAdvice
    public class UserException {
        
        @ExceptionHandler({NullPointerException.class})
        public ModelAndView handlerNullPointerException(Exception ex){
            System.out.println("[异常] : " + ex);
            ModelAndView mav = new ModelAndView("error");
            mav.addObject("exception",ex);
            return mav;
        }
    }

    当然在开发我们可能在上面的类中有两个方法例如一个是RuntimeException和NullPointerException那么他会调用那个捕获方法呢?

    它不会应为RuntimeException可以匹配就匹配这个他会根据最靠近这个异常的类型去匹配。

    定制异常页面

    在网站中如果我们发生页面不存在我们能够看到页面显示:

    在这里我们可以自定义异常显示。我们可以定义一个异常类使用@ResponseStatus注解修饰

    package com.spring.mvc.exception;
    
    import org.springframework.http.HttpStatus;
    import org.springframework.web.bind.annotation.ResponseStatus;
    
    /**
     * @author SimpleWu
     * 当捕获当这个异常后更改错误提示
     */
    @ResponseStatus(value=HttpStatus.FORBIDDEN,reason="用户密码为空")
    public class UserPassIsNullException extends RuntimeException{
        private static final long serialVersionUID = 1L;
    }

    在这里我们定义了一个异常,如果在请求的方法中抛出我们的异常,页面就会显示我们定制的状态码与提示信息。

    SimpleMappingExceptionResolver:

    如果希望对异常进行统一处理我们可以装配这个bean,将它的异常类名映射为视图名,发生异常时使用对应视图报告异常

    <!-- 
            配置SimpleMappingExceptionResolverl来映射异常
            相当于捕获一个全局异常
         -->
        <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            
            <!-- 自定义异常属性名字 -->
            <property name="exceptionAttribute" value="ex"/>
            <property name="exceptionMappings">
                <props>
                    <!-- 捕获到java.lang.ArithmeticException异常跳转error.jsp页面 -->
                    <prop key="java.lang.ArithmeticException">error</prop>
                </props>
            </property>
        </bean>

    如果我们捕获到这个算数异常那么我们就会返回error视图。本该在jsp中我们的页面上显示异常默认使用exception现在名字换成了ex

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-5 20:42 , Processed in 0.059746 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表