SpringMVC的拦截器和异常处理器

目录

lerInterceptor 拦截器

1、拦截器的作用

2、拦截器的创建

3、拦截器的三个抽象方法

4、拦截器的配置

5、多个拦截器的执行顺序

SpringMVC的异常处理器

1、异常处理器概述

2、基于配置文件的异常处理

3、基于注解的异常处理


lerInterceptor 拦截器

1、拦截器的作用

拦截器的作用时机

SpringMVC的拦截器作用于 控制器方法执行的前后

有不同的拦截方法,作用于控制器方法执行之前、之后、以及视图渲染之后三个阶段

拦截器与过滤器的区别

过滤器是原生Serlvet的组件,作用于Servlet执行之前

拦截器是SpringMVC的模块,作用于控制器方法执行前、后、渲染视图后。

2、拦截器的创建

SpringMVC中的拦截器需要实现HandlerInterceptor接口

示例

public class FirstInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("控制器方法准备执行...");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("控制器方法执行完毕...");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("视图渲染完毕...");
    }
}

3、拦截器的三个抽象方法

HandlerInterceptor接口有三个抽象方法:

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

源码分析,为什么preHandle能实现拦截控制器方法

//DispatherServlet
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    //如果applyPreHandle方法返回的是false,就直接return,不再执行下面的内容
    return;
}

//执行控制器方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//渲染视图
...


//applyPreHandle方法
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    for (int i = 0; i < this.interceptorList.size(); i++) {
        HandlerInterceptor interceptor = this.interceptorList.get(i);
        if (!interceptor.preHandle(request, response, this.handler)) {
            triggerAfterCompletion(request, response, null);
            //如果当前拦截器的preHandle方法返回false,applyPreHandle方法也返回false
            return false;
        }
        this.interceptorIndex = i;
    }
    return true;
}

注意

SpringMVC配置文件中的view-controller视图控制器标签,也会被拦截器拦截

4、拦截器的配置

SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置。

拦截器有三种配置方式,一般使用第三种,可以配置拦截范围。

方式一 在interceptors中配置自定义拦截器的bean标签

<!--配置拦截器-->
<mvc:interceptors>
    <bean class="com.csai.interceptors.FirstInterceptor"/>
</mvc:interceptors>

这种方式无法指定拦截范围,是对DispatcherServlet所处理的所有的请求进行拦截

方式二 在interceptors中引用自定义拦截器的bean id

<bean id="firstInterceptor" class="com.csai.interceptors.FirstInterceptor"/>

<!--配置拦截器-->
<mvc:interceptors>
    <ref bean="firstInterceptor"/>
</mvc:interceptors>

和上面一样,这种方式无法指定拦截范围,是对DispatcherServlet所处理的所有的请求进行拦截

配置自定义拦截器的bean时,可以使用配置文件,也可以使用@Component注解+组件扫描的方式

方式三 使用<mvc:interceptor>标签进行配置

<bean id="firstInterceptor" class="com.csai.interceptors.FirstInterceptor"/>

<!--配置拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/testInterceptor"/>
        <ref bean="firstInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

可以配置三个属性:

  • mapping拦截请求的请求地址,可以使用Ant风格的路径
  • exclude-mapping不会被拦截的请求地址,即拦截白名单
  • bean/ref:指定拦截器的bean

例如这里是拦截所有请求,不拦截testInterceptor页面,对应的拦截器是firstInterceptor

5、多个拦截器的执行顺序

如果匹配到的多个拦截器的preHandle()方法都返回true

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

  • preHandle()会按照配置的顺序执行,即先配置的先执行

  • postHandle()和afterComplation()会按照配置的反序执行,即先配置的后执行,因为是嵌套的关系。

示例,请求访问,匹配到一个控制器方法,两个拦截器:

配置顺序:

<!--配置拦截器-->
<mvc:interceptors>
    <ref bean="Interceptor A"/>
    <ref bean="Interceptor B"/>
</mvc:interceptors>

执行顺序:

preHandle A --> true

preHandle B --> true

--- 控制器方法执行 ---

--- 控制器方法执行完毕 ---

postHandle B

postHandle A

--- 视图渲染完毕 ---

afterComplation B

afterComplation A

如果匹配到多个拦截器,有的拦截器的preHandle()方法返回了false

先看结果:对于同一个控制器方法,只要存在拦截器的preHandle()方法返回了false,控制器方法就不会执行。

  • 在它之前配置的拦截器,和它自己的preHandle()都会执行
  • 所有的postHandle()都不执行,因为控制器方法没有执行
  • 在它之前配置的拦截器,afterComplation()会执行
  • 在它之后配置的拦截器,所有方法都不会执行。

示例 请求访问,匹配到一个控制器方法,两个拦截器,其中一个返回false:

配置顺序:

<!--配置拦截器-->
<mvc:interceptors>
    <ref bean="Interceptor A"/>
    <ref bean="Interceptor B"/>
</mvc:interceptors>

Interceptor B 的preHandle()返回false

执行顺序:

preHandle A --> true

preHandle B --> false

--- 控制器方法不执行 ---

afterComplation A

SpringMVC的异常处理器

1、异常处理器概述

异常处理器的作用

用于处理SpringMVC 控制器方法执行过程中 产生的异常。

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

HandlerExceptionResolver接口的实现类:

  • DefaultHandlerExceptionResolver,是SpringMVC默认使用的异常处理器
  • SimpleMappingExceptionResolver,用于自定义 异常处理器

自定义异常处理器的使用场景

大致有两个作用:

  1. 对系统异常提供自定义处理。比如出现某个异常时,跳转到服务器繁忙的页面,用户就不会看到500这类的页面了
  2. 提供对自定义异常的处理方案

2、基于配置文件的异常处理

SpringMVC提供了自定义的异常处理器SimpleMappingExceptionResolver

示例 实现错误页面跳转

<!--配置异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!--如果出现ArithmeticException数学异常,就跳转到error视图-->
            <prop key="java.lang.ArithmeticException">error</prop>
        </props>
    </property>
</bean>

properties的键表示处理器方法执行过程中出现的异常

properties的值表示若出现指定异常时,设置一个新的视图名称,跳转到指定页面

测试

error页面

<h3>服务器繁忙!</h3>

控制器方法

@RequestMapping("/testInterceptor")
public String testInterceptor(){
    //创造一个数学异常
    Integer i = 3/0;
    return "success";
}

发生异常后,就会被自定义的异常处理器捕获,跳转到错误页面

示例 实现异常信息的捕获

配置文件

<!--配置异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!--如果出现ArithmeticException数学异常,就跳转到error视图-->
            <prop key="java.lang.ArithmeticException">error</prop>
        </props>
    </property>
    <property name="exceptionAttribute" value="exception"/>
</bean>

配置exceptionAttribute属性,设置一个value

异常信息就会存入request域中,键名为设置的value,值为异常信息。

前端页面展示错误信息

<h3>服务器繁忙!</h3>
<p th:text="${exception}"></p>

3、基于注解的异常处理

使用注解,实现获取异常信息和跳转错误页面

@ControllerAdvice
public class ExceptionController {

    @ExceptionHandler(value = {ArithmeticException.class})
    public String testException(Exception exception, Model model){
        model.addAttribute("exception", exception);
        return "error";
    }

}

原理:如果遇到了@ExceptionHandler 注解 标识的这些异常,就调用 此 @ExceptionHandler 注解对应的控制器方法。

使用注解,在配置文件中就不需要配置任何关于异常处理器的内容。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
拦截器和过滤的区别 1、拦截器基于动态代理 , 过滤基于函数回调 2、拦截器不依赖于servlet,通过动态代理实现,过滤依赖于servlet 3、拦截器在方法前后,异常前后等调用,而过滤只能在请求前和请求后各调一次。 4、拦截器可以利用依赖注入,因此在spring框架程序中,优先拦截器 5、拦截器是包裹在过滤中使用的。 复习 converter 转换 i18n struts2 spring MVC 拦截器 interceptor 过滤 filter web.xml implements filter filterchain arg2.doFilter(req,resp); 监听 servlet application /session /request 6/8 个 1、拦截器 定义拦截器的包 <package name="myPackage" extends="struts-default"> 定义拦截器的核心 <interceptors> 定义拦截器类 <interceptor name="myInterceptor" class="util.MyInterceptor"></interceptor> 定义拦截器的值栈空间 <interceptor-stack name="myStack"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="myInterceptor"></interceptor-ref> </interceptor-stack> </interceptors> 引入定义的拦截器 <default-interceptor-ref name="myStack"></default-interceptor-ref> 拦截错误跳转的页面 <global-results> <result name="error">/demo01/error.jsp</result> </global-results> </package> 2、 token <package name="testMg" extends="struts-default"> <action name="testAction_*" class="view.TestAction" method="{1}"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="token"></interceptor-ref> <result name="invalid.token">/demo02/error.jsp</result> </action> </package> <%@ taglib uri="/struts-tags" prefix="s" %> <s:token></s:token> 3、500字struts2的科学说明文 每人一份 2018-03-19 下午演讲(脱稿) 4、小结 1、struts2对servlet封装(request,response) ,资源调配和资源的映射 2、框架设计的思想 istruts 配置,过滤,反射 istruts.properties 3、starts2的使用思路 1、jar 2、配置文件 3、常用类 servletActionContext 4、访问流程 url -> filter -> struts.xml -> package -> action -> name="userAction_*" -> class -> method="{1}" 5、核心struts.xml 6、提交策略 图片预览 个人信息完善 7、crud 增删改查 搜索 多删 假删 ids ->action -> dao PreparedStatement -- "delete from user where id in ("+ids+")"; 8、converter i18n ModeDriven stack 9、interceptor token 5、hibernate 4.1.4 搭建架构 ORM --- Object relational Mapping UserBean userBean.hbm.xml db table let java objects hibernate in the relational datebase ! persistent Class

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值