【SpringMVC】SpringMVC中拦截器和异常处理机制的使用

目录

1.拦截器

1.1 概念 

1.2 使用拦截器

preHandle() 方法

postHandle 方法

afterCompletion ()方法

拦截器和过滤器的区别(面试题)

2.Spring MVC 异常处理

 2.1 局部配置

2.2 全局配置

 2.3 使用配置文件配置

2.4 根据状态码跳转到指定页面


1.拦截器

【前言】

        过滤器的作用是保护请求的服务器资源,在请求资源被执行之前,如果请求地址符合拦截范围,则会先执行过滤器。过滤器的执行时机,是在 Servlet 之前执行的。但是在使用了SpringMVC 后,Servlet 只有一个了,也就是 DisptcherServlet。

        而如果我们仍然使用过滤器来完成请求的拦截,但过滤器是在 Servlet 之前执行的,过滤器会拦截 DispatcherServlet 所有的请求。那么,如果我 们有部分请求不想被拦截,怎么办呢?

1.1 概念 

SpringMVC 给出了拦截器来实现单元方法的拦截,拦截器的执行是在 DispatcherServlet 之后和单元方法之前的,这样我们就可以在单元方法被之前对请求进行自定义的拦截处理了。 【注意】只有 URL 匹配到了控制单元,拦截器才能生效

1.2 使用拦截器

(1)创建拦截器

通过实现 HandlerInterceptor 接口,或继承 HandlerInterceptor 接口的实现类(如 HandlerInterceptorAdapter)来定义。这里我们主要使用实现 HandlerInterceptor 接口的方式创建。

package com.wollo.interceptor;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor3 implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
        /**
         * 作用:
         *      拦截单元方法的请求
         * 执行时机:
         *      在DispatcherServlet之后,单元方法之前
         * @param request 封装了此次请求的请求数据的request对象
         * @param response 此次请求的响应对象
         * @param handler HandlerMethod,HandlerMethod对象中存储了此次请求的单元方法的Method对象
         * @return 返回true表示放行继续执行单元方法,返回false表示拦截。
         * @throws Exception
         */
        return true;
    }


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        /**
         * 作用:
         *    对作用域中的数据进行一些操作,比如:敏感词汇的脱敏
         * 执行时机:
         *      在单元方法之后执行,转发的页面资源之前
         * @param request 封装了此次请求的请求数据的request对象
         * @param response 此次请求的响应对象
         * @param handler HandlerMethod,HandlerMethod对象中存储了此次请求的单元方法的Method对象
         * @param modelAndView: 包含了Model对象和View对象,Model对象存储了此次转发的作用域数据,View存储了转发资源路径
         *                注意: DispatcherServlet在调用完成单元方法后底层会创建ModelAndView对象来存储单元方法跳转的视图以及作用域对象
         * @throws Exception
         */
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        /**
         * 作用:
         *    记录请求处理的日志信息或者对请求处理过程中的异常进行统一的处理
         * 时机:
         *  在preHandle放行的情况下,不管中间执行流程是否出现异常,afterCompletion方法都会被调用
         * @param request 封装了此次请求的请求数据的request对象
         * @param response 此次请求的响应对象
         * @param handler HandlerMethod,HandlerMethod对象中存储了此次请求的单元方法的Method对象
         * @param ex
         * @throws Exception
         */
    }
}

【该拦截器中的方法介绍】

preHandle() 方法

postHandle 方法

afterCompletion ()方法

(2)配置拦截器

拦截器类创建好后需要在 springmvc.xml 文件中配置拦截器的 bean 以及其拦截范围。

 <!--配置拦截器-->
   <mvc:interceptors>
        <!--01 这个是配置全局拦截: 拦截所有的单元方法-->
        <bean id="my" class="com.wollo.interceptor.MyInterceptor"></bean>   
       
       <!--02 这个是配置指定拦截;-->
        <mvc:interceptor>
            <mvc:mapping path="/demo"/><!--配置拦截的单元方法-->
            <mvc:mapping path="/demo2"/>
            <bean class="com.wollo.interceptor.MyInterceptor2"></bean><!--配置拦截器-->
        </mvc:interceptor>
    </mvc:interceptors>

(3)代码书写测试。

不配置拦截器的情况

访问 

可以看到可以正常访问。

配置拦截器

输入请求地址再次访问

可以看到显示页面空白,且控制台执行了拦截器中的preHandle()方法。

至此页面被拦截成功,而现在我们对单元方法转发的资源进行拦截。

需求:对页面中的中国两个字进行 **号替换。

拦截器的配置和以前一样,在单元方法中设置一个全局对象值为“中国人”,然后能直接在页面展示出来如下图

现在我们在拦截器中的postHandle()中对资源进行拦截

现在,再次访问,可以得到如下页面

至此,对请求资源的拦截成功!

【说明】拦截器中是存在多重拦截的,当我们访问一个单元方法时,如果该单元方法符合多个拦截器的拦截范围则符合的拦截器都会执行,执行顺序按照配置文件中配置的拦截器自上而下执 行 :preHandle 配置上 --->prehandle 配置下 ---> 单元方法 --->postHandle 配置下 --- >postHandle 配置上 --->afterCompletion 配置上 --->afterCompletion 配置下

图解如下

拦截器和过滤器的区别(面试题)

  1. 来源不同: 拦截器是 SpringMVC 中的技术,过滤器是 Java EE 中的技术
  2. 生效位置不同: 拦截器是进入 DispatcherServlet 后才能执行,过滤器是进入到 DispatcherServlet 容器前就可以触发。
  3. 目标不同 :拦截器拦截的目标是 HandlerMethod(控制单元,控制器方法),过滤器可以过滤所有的 URL。
  4. 运行机制不同: 拦截器是在 HandlerMethod 之前和视图处理完成后执行,分为三部分。过滤器只能在目标资源前后执行。
  5. 接口中方法类型不同: 拦截器中的方法都是 default 方法,可以重写也可以不重写。过滤器中的方法都是 abstract 方 法,如果当前类不是抽象类,必须重写。
  6. 上下文不同 :拦截器可以获取到 Spring 容器中内容,但是 Filter 因为是被 Tomcat 管理,所以无法获取 Spring 容器内容。

2.Spring MVC 异常处理

在 Spring MVC 支持异常处理。不会呈现给用户 500 界面。而是当出现异常时交给某个特定的 控制器。

 2.1 局部配置

  • 配置在@Controller 的控制器类中,只有当前这个控制器类的控制单元出现异常时才能执行, 其他类的控制单元出现异常不能执行 。
  • 每个控制器类中可以有多个处理异常的方法。每个方法上面只需要@ExceptionHandler

2.2 全局配置

创建一个异常处理类,在类上使用@ControllerAdvice ,因为该注解已经继承了@Component 注解,所以类上只添加这个注解就可以了,不需要在添加@Controller 注解了。

 2.3 使用配置文件配置

  • 在 Spring MVC 中包含 HandlerExceptionResolver 组件,专门负责处理异常的。接口中只包 含一个 resolveException 方法,程序员可以自行对接口实现,也可以使用 Spring MVC 提供的实现。
  • 想要在异常出现时跳转到指定页面,只需要在 springmvc.xml 文件中添加异常解析器即可。 

下面的配置表示当出现空指针异常时跳转到 /error1.jsp,其他异常都跳转到 /error2.jsp

注意:配置文件优先级低于注解的方式

2.4 根据状态码跳转到指定页面

在 Spring MVC 框架中没有提供根据状态码跳转到特定的视图。想要实现根据状态码跳转到指 定页面可以使用 Java EE 中提供的实现方案,在 web.xml 中配置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值