SpringMVC拦截器

该博客仅为本人学习时笔记记录。不能保证没有错误,请结合自己思想参考。

项目源码:
github地址:https://github.com/JYG0723/springmvcpractice/tree/master

什么是拦截器

拦截器的作用:
1. 拦截器就是浏览器发送往wen服务器的请求。来对他请求的数据或者返回的数据 做一些更改,或者在请求的执行之前或者在请求的执行之后加入一些代码。 以此来对一些请求的功能进行增强

拦截器的应用场景:
1. 稍大一些的工程中,会有许多请求。许多请求中有一些共性的问题。这些共性的问题就可以放到拦截器中去处理,(比如乱码问题。权限验证问题and so forth)

拦截器的工作原理

如果不考虑拦截器和过滤器具体细节的时候。两者作用是非常相似的,对请求进行增强处理,同时对应用程序的一些功能进行增强的目的。

拦截器的实现

xmlns是XML Namespaces的缩写。XML命名空间
xsd是 XML结构定义。格式描述文件

  1. 编写拦截器类,实现 HandlerInterceptor 接口。
  2. 将拦截器注册进 SpringMVC 框架中。
  3. 配置拦截器的拦截规则。

TestInterceptor:

package nuc.jyg.interceptor;

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

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

/**
 * @Author Nuc YongGuang Ji
 * Created by JiYongGuang on 2017/5/17.
 */
public class TestInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

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

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

mvc-dispatcher-servlet.xml:

    <!-- Configure Interceptor -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/hello/testPut"/>
            <bean class="nuc.jyg.interceptor.TestInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/interceptor"/>
            <bean class="nuc.jyg.interceptor.TestInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

InterceptorController:


/**
 * @Author Nuc YongGuang Ji
 * Created by JiYongGuang on 2017/5/17.
 */
@Controller
public class InterceptorController {

    @RequestMapping(value = "/interceptor")
    public void testInterceptor(HttpServletResponse servletResponse) throws IOException {
        PrintWriter pw = servletResponse.getWriter();
        pw.print("hello interceptor");
        pw.print("hello interceptor");
        System.out.println("InterceptorController class");
    }
}

HelloMvcController:

/**
 * @Author Nuc YongGuang Ji
 * Created by JiYongGuang on 2017/5/10.
 */
@Controller
@RequestMapping("/hello")
public class HelloMvcController {

    Logger logger = LoggerFactory.getLogger(HelloMvcController.class);

   /*
    *   Put Request Method Test From Form
    *
    * */
    @RequestMapping(value = "/testPut", method = RequestMethod.PUT)
    @ResponseBody
    public String testGet() {
        System.out.println(1);
        return "putMethod";
    }
拦截器方法介绍:

1.preHandle:请求被处理之前进行调用。决定是否将当前请求拦截下来。(返回true请求继续运行,返回false请求终止(Object arg 代表被拦截的目标对象(类)。可以通过这个参数获取到该对象其中的一些内容)
2.postHandle:请求被处理之后进行调用。(ModelAndView对象可以改变发往的视图(setViewName)或修改发往视图的信息内容(addObject方法的同名信息覆盖)。
3.afterCompletion:请求结束之后进行调用。表示视图显示之后再执行该方法。(一般用于资源的销毁,不会常用)

TestInterceptor:

package nuc.jyg.interceptor;

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

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

/**
 * @Author Nuc YongGuang Ji
 * Created by JiYongGuang on 2017/5/17.
 */
public class TestInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        System.out.println(handler.getClass().toString());
        System.out.println(handler.getClass().getDeclaredMethods().toString());
        System.out.println("preHandle /======== =========/");

        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
//        modelAndView.setViewName("index.jsp");
//          modelAndView.addObject("addd",23);
        System.out.println("postHandle /======== =========/");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}
多个拦截器应用

一个应用多个拦截器包裹的执行流程图:


可以结合上图来理解。
去的时候收费站1,收费站2(preHandler)
回来的时候收费站1,收费站2(postHandler)
回到家后收到的发票1,发票2(afterCompletion)

如果我们从出发地南方,去往目的地天安门。要先经过收费站1,然后经过收费站2.当我们返回的时候,需要先经过收费站2,再经过收费站1.当我们回到家后,肯定是先经过的收费站2的发票到达我们这里,然后才是后经过的收费站1的发票到达我们这里。

mvc-dispatcher-servlet.xml:

<!-- Configure Interceptor -->
        <!-- 拦截所有请求 -->
        <bean class="nuc.jyg.interceptor.TestInterceptor2"/>
        <bean class="nuc.jyg.interceptor.TestInterceptor"/>
    </mvc:interceptors>

多个拦截器执行的先手顺序取决于 配置拦截器的顺序。

拦截器的其他实现方式

实现 WebRequestInterceptor 接口。

方法名与原来的方法名一致,参数有所区别。同时 preHandler 方法没有返回值。所以不可以在 preHandler 方法中终止请求。所以一般用功能更齐全的 HandlerInterceptor 接口。

两者向 SpringMVC 配置文件的注册方式一致。

拦截器的使用场景

使用原则:处理所有请求的共性问题。

  1. 解决乱码问题。
  2. 解决权限验证问题。
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("TestInterceptor2 preHandle");

        //resolver garbled problems
        request.setCharacterEncoding("utf8");

      /*
        System.out.println(handler.getClass().toString());
        System.out.println(handler.getClass().getDeclaredMethods().toString());
        System.out.println("TestInterceptor2 preHandle /======== =========/");
      */

        //解决权限验证问题
        if (request.getSession().getAttribute("user") == null) {
            request.getRequestDispatcher("login.jsp").forward(request, response);
            return false;
        }

        return true;
    }
拦截器和过滤器的区别

不难发现拦截器和过滤器作用处非常相似。

过滤器:过滤器Filter依赖于Servlet容器。基于回调函数,过滤范围大。除了可以 过滤所有请求,还可以过滤一些资源

拦截器:拦截器Interceptor依赖于框架容器。基于反射机制,只过滤向 控制器中映射了的请求路径的请求。对于向未映射的路径的请求不予处理

总结

拦截器可以处理web应用请求中的一些共性问题。
共性问题在拦截器中处理,可以减少重复代码。便于维护。

SpringMVC整个模块流程图:
图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值