SpringMVC学习04:异常处理器和拦截器

SpringMVC学习04:异常处理器和拦截器

异常处理器

当程序发生错误时,错误最终会传递给DispatcherServlet,由DispatcherServlet进行异常处理.

下面演示使用SpringMVC的异常处理机制处理异常

  1. 创建自定义异常类

    package cn.maoritian.exception;
    
    public class SysException extends Exception {
    
        // 存储提示信息的
        private String message;
    
        // 构造方法
        public SysException(String message) {this.message = message; }
    
        // get,set方法
        public String getMessage() {return message; }
        public void setMessage(String message) {this.message = message; }
    }
    
  2. 创建异常处理器,异常处理器必须实现HandlerExceptionResolver接口,其resolveException()方法执行异常处理.

    package cn.maoritian.exception;
    
    // 自定义异常处理器
    public class MyExceptionResolver implements HandlerExceptionResolver {
    
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    
            myException e = null;
            if (ex instanceof myException) {
                e = (myException) ex;
            } else {
                e = new myException("其他错误");
            }
            
            ModelAndView mv = new ModelAndView();
            mv.addObject("errorMsg", e.getMessage());   // 封装错误信息
            mv.setViewName("error");                    // 跳转页面
            return mv;
        }
    }
    
  3. 向Spring容器中注入异常处理器

    <!--配置异常处理器-->
    <bean id="myExceptionResolver" class="cn.maoritian.exception.MyExceptionResolver"/>
    

这样,SpringMVC就能处理异常了.

拦截器

拦截器的配置

SpringMVC中的拦截器只能拦截Controller中的方法,下面演示拦截器的使用

  1. 自定义拦截器需要继承HandlerInterceptor接口,该接口中定义了三个方法,都已有其默认实现:

    • preHandle(...): 该方法在处理器方法实际执行之前执行
    • postHandle(...): 该方法在处理器方法实际执行完毕以后执行
    • afterCompletion(...): 该方法在整个请求处理完成后执行

    其中preHandle(..)方法返回一个boolean值,可以通过这个方法来决定是否继续执行处理链中的部件。当方法返回 true时,处理器链会继续执行;若方法返回 falseDispatcherServlet即认为拦截器自身已经完成了对请求的处理(比如说,已经渲染了一个合适的视图),那么其余的拦截器以及执行链中的其他处理器就不会再被执行了。

    package samples;
    
    public class TimeBasedAccessInterceptor extends HandlerInterceptor {
    
        private int openingTime;
        private int closingTime;
        
        public void setOpeningTime(int openingTime) {this.openingTime = openingTime; }
        public void setClosingTime(int closingTime) {this.closingTime = closingTime; }
    
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            Calendar cal = Calendar.getInstance();
            int hour = cal.get(HOUR_OF_DAY);
            if (openingTime <= hour && hour < closingTime) {
                return true;
            }
            response.sendRedirect("http://host.com/outsideOfficeHours.html");
            return false;
        }
    }
    
  2. 向Spring容器中注入拦截器

    <mvc:interceptors>
    
        <mvc:interceptor>
            <!-- 拦截的方法 -->
            <mvc:mapping path="/**" />
            <!-- 具体的拦截器 -->
            <bean id="officeHoursInterceptor" class="cn.maoritian.interceptor.TimeBasedAccessInterceptor">
                <property name="openingTime" value="9"/>
                <property name="closingTime" value="18"/>
            </bean>
        </mvc:interceptor>
    
    </mvc:interceptors>
    

多个拦截器的执行顺序

多个拦截器的执行顺序是由外向内分层执行的

配置两个拦截器如下:

<!-- 配置三个拦截器 -->
<mvc:interceptors>

    <!-- 配置拦截器1 -->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.maoritian.controller.cn.maoritian.interceptor.MyInterceptor1"/>
    </mvc:interceptor>

    <!-- 配置拦截器2 -->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.maoritian.controller.cn.maoritian.interceptor.MyInterceptor2"/>
    </mvc:interceptor>
    
    <!-- 配置拦截器3 -->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.maoritian.controller.cn.maoritian.interceptor.MyInterceptor3"/>
    </mvc:interceptor>
    
</mvc:interceptors>

访问该域名下Handler时,服务器输出如下:

Interceptor1的preHandle()方法执行了
Interceptor2的preHandle()方法执行了
Interceptor3的preHandle()方法执行了
Handler中的方法执行了
Interceptor3的postHandle()方法执行了
Interceptor2的postHandle()方法执行了
Interceptor1的postHandle()方法执行了
跳转到的jsp中的java脚本执行了
Interceptor3的afterCompletion()方法执行了
Interceptor2的afterCompletion()方法执行了
Interceptor1的afterCompletion()方法执行了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值