42.SpringMVC拦截器和异常处理器

SpringMVC拦截器和异常处理器

过滤器:在浏览器和目标资源之间过滤

拦截器:用于拦截控制器方法的执行

SpringMVC中的拦截器需要实现HandlerInterceptor接口,使用拦截器必须在SpringMVC的配置之前先进行配置

拦截器的三个抽象方法

  • preHandle:控制器方法执行之前执行,其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法返回false表示拦截,即不调用控制器方法
  • postHandle:控制器方法执行之后执行
  • afterCompletion:处理完视图和模型数据,渲染视图完毕之后执行

FirstInterceptor.java

package com.atguigu.SpringMVC.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class FirstInterceptor implements HandlerInterceptor {
    //Ctrl+O提示可以重写的方法
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("FirstInterceptor-->preHandle");
        //为true则放行
        return true;
    }

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

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

SpringMVC.xml

    <mvc:interceptors>
<!--        <bean id="firstInterceptor" class="com.atguigu.SpringMVC.interceptor.FirstInterceptor"/>-->
<!--        <ref bean="firstInterceptor"/>-->
        <!-- 以上两种配置方式都是对DispatcherServlet所处理的所有的请求进行拦截 -->
        <mvc:interceptor>
            <!--设置需要拦截请求:"/*"代表拦截下一层目录的所有请求,"/**"代表拦截任意层数所有请求-->
            <mvc:mapping path="/**"/>
            <!--排除不需要拦截的请求-->
            <mvc:exclude-mapping path="/hello"/>
            <ref bean="firstInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

成功拦截控制器跳转:

FirstInterceptor–>preHandle
FirstInterceptor–>postHandle
FirstInterceptor–>afterCompletion

满足条件放行(访问/hello):

FirstInterceptor–>preHandle

多个拦截器的执行顺序

  • 若每个拦截器的preHandle()都返回true

    • 此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关:
      • preHandle()会按照配置的顺序执行,而postHandle()和afterCompletion()会按照配置的反序执行
  • 若某个拦截器的preHandle()返回了false

    • 拦截器的preHandle()返回false和它之前的拦截器的preHandle()都会执行postHandle()都不执行,返回false的拦截器之前的拦截器的afterCompletion()会执行

异常处理器

基于配置的异常处理

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

HandlerExceptionResolver接口的实现类有:DefaultHandlerExceptionResolverSimpleMappingExceptionResolver

使用方式:SpringMVC.xml

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

error.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>error</h1>
    <!--访问保存在请求域中的共享数据-->
    <p th:text="${ex}"></p>
</body>
</html>

给(“/hello”)添加输出——1 / 0,触发数学运算异常,运行效果

基于注解配置的异常

ExceptionController.java

package com.atguigu.SpringMVC.controller;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice //将当前类标识为异常处理的组件
public class ExceptionController {
    //用于设置方法需要处理的异常
    @ExceptionHandler(ArithmeticException.class)
    //ex表示当前请求处理中出现的异常对象
    public String handlerException(Throwable ex, Model model){
        model.addAttribute("ex",ex);
        return "error";
    }
}

运行结果:和上面保持一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值