12_SpringMVC_拦截器

在之前学习JAVAWEB 的时候,我们学习了过滤器的知识。过滤器的作用是保护请求的服务器资源,在请求资源被执行之前,如果请求地址符合拦截范围,则会先执行过滤器。过滤器的执行时机,是在Servlet之前执行的。但是在使用了SpringMVC后,Servlet只有一个了,也就是DisptcherServlet。那么,如果我们仍然使用过滤器来完成请求的拦截,因为过滤器是在Servlet之前执行的,就会造成,过滤器会拦截DispatcherServlet所有的请求。那么,如果我们有部分请求不想被拦截,怎么办?

拦截器使用

Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。

要使用Spring MVC中的拦截器,就需要对拦截器类进行定义和配置。通常拦截器类可以通过两种方式来定义。

1.通过实现HandlerInterceptor接口,或继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来定义。

2.通过实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类来定义。

拦截器和过滤器的区别

1拦截器SpringMVC的,而过滤器是servlet的。

  2拦截器不依赖与servlet容器,由spring容器初始化,过滤器依赖与servlet容器,由servlet容器初始化。

  3拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

  4拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

  5在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

6拦截器可以获取IOC容器中的各个bean,而过滤器就不太方便,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

定义一个拦截器

package com.msb.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * @Author: Ma HaiYang
 * @Description: MircoMessage:Mark_7001
 */
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /*在请求到达我们定义的handler之前工作的*/
        System.out.println("MyInterceptor preHandle");
        /*返回的是true,代表放行,可以继续到达handler*/
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor postHandle");
        /*handler 处理单元返回ModelAndView 时候进行 拦截*/
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        /*
        页面渲染完毕,但是还没有给浏览器响应数据的时候
         */
        System.out.println("MyInterceptor afterCompletion");
    }
}

springmvc.xml中注册拦截器

   <!--注册拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/login.action"/>
            <bean id="myInterceptor" class="com.msb.interceptor.MyInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

拦截器内容详解

1、preHandle方法

执行时机

再进入控制单元方法之前执行

如何调用

按拦截器定义顺序调用

具体作用

如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去 进行处理,则返回 true。 如果程序员决定不需要再调用其他的组件去处理请求,则返回 false。

参数详解

HttpServletRequest arg0,拦截的请求的request对象

HttpServletResponse arg1, 拦截的请求的response对象

Object arg2 封存了单元方法对象的HandleMethod对象

/**
     *
     * @param request  请求对象
     * @param response 响应对象
     * @param handler  目标要调用的Handler
     * @return 返回true放行,返回false拦截
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /*在请求到达我们定义的handler之前工作的*/
        System.out.println("MyInterceptor preHandle");
        /*设置请求和响应的乱码 */
        /* request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");*/
        // 判断是否登录
        /*User user =(User) request.getSession().getAttribute("user");
        if(null == user)
            response.sendRedirect("index.jsp");
        return false;*/
        // 用户权限控制
        return true;
    }

2、postHandle方法

执行时机

在进行数据处理和做出响应之间进行这个方法的调用

如何调用

在拦截器链内所有拦截器返成功调用

具体作用

在业务处理器处理完请求后,但是 DispatcherServlet 向客户端返回响应前被调用,

在该方法中对用户请求 request域数据进行处理。

参数详解

HttpServletRequest arg0, 拦截的请求的request对象

HttpServletResponse arg1, 拦截的请求的response对象

Object arg2, 封存了单元方法对象的HandleMethod对象

ModelAndView arg3 封存了单元方法的返回值资源路径和请求转到的Map数据

/**
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView  controller响应的结果,视图和数据
     * @throws Exception
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor postHandle");
        /*控制数据*/
        /*Map<String, Object> map = modelAndView.getModel();
        String msg = (String)map.get("msg");
        String newMsg = msg.replaceAll("脏话", "**");
        map.put("msg", newMsg);*/
        /*控制视图*/
        /*modelAndView.setViewName("/testDemo1.jsp");*/
    }

3、afterCompletion方法

执行时机

在进行页面渲染的时候执行

如何调用

按拦截器定义逆序调用

具体作用

在DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。

参数详解

HttpServletRequest arg0, 拦截的请求的request对象

HttpServletResponsearg1, 拦截的请求的response对象

Object arg2, 封存了单元方法对象的HandleMethod对象

Exception arg3 存储了责任链的异常信息

/**
     * 无论controller是否出现异常,都会执行的方法
     *  一般来说都做一些资源释放工作
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        /*页面渲染完毕,但是还没有给浏览器响应数据的时候*/
        System.out.println("MyInterceptor afterCompletion");
        System.out.println(ex);
    }

多个拦截器执行顺序

多个拦截器同时存在时,执行的顺序由配置顺序决定. 先配置谁, 谁就先执行.多个拦截器可以理解为拦截器栈, 先进后出(后进先出), 如图所示:

<!--注册拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/login.action"/>
            <bean id="myInterceptor1" class="com.msb.interceptor.MyInterceptor"></bean>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/login.action"/>
            <bean id="myInterceptor2" class="com.msb.interceptor.MyInterceptor2"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

MyInterceptor preHandle

MyInterceptor2 preHandle

login.action

MyInterceptor2 postHandle

MyInterceptor postHandle

success.jsp

MyInterceptor2 afterCompletion

MyInterceptor afterCompletion

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java拦截是在请求到达目标方法之前或之后,对请求进行拦截、处理或修改的一种机制。在SpringMVC中,可以通过实现HandlerInterceptor接口来编写拦截。 下面是一个实现拦截的示例: 1. 创建一个类实现HandlerInterceptor接口,并实现其三个方法:preHandle、postHandle和afterCompletion。 ```java public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在请求处理之前进行调用(Controller方法调用之前) System.out.println("拦截 preHandle 方法被调用"); return true; // 只有返回true才会继续向下执行,返回false取消当前请求 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后) System.out.println("拦截 postHandle 方法被调用"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要用于进行资源清理工作) System.out.println("拦截 afterCompletion 方法被调用"); } } ``` 2. 在SpringMVC的配置文件中配置拦截。 ```xml <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.example.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors> ``` 上述代码中,将拦截配置为对所有请求进行拦截。也可以根据需要进行配置。 通过以上配置,拦截就可以在请求到达Controller之前、之后和整个请求结束后执行相应的操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值