Spring MVC拦截器

[复制链接]
发表于 昨天 06:22 | 显示全部楼层 |阅读模式
一、什么是拦截器

拦截器是 SpringMVC 提供的一种可以在哀求处理处罚过程中对哀求举行预处理处罚或后处理处罚的机制。简朴来说,拦截器就像是一位“守门员”,它拦住全部进来的哀求,根据设定的规则决定是否放行大概举行某些操纵。
拦截器可以:

  • 在哀求进入 Controller 之前做一些操纵(如权限查抄、日记记载、性能监控监控等)。
  • 在哀求返回前做一些操纵(如对返回数据举行修改、记载日记等)。
二、拦截器和过滤器的区别

拦截器与过滤器(Filter)有很多相似之处,它们都可以对 HTTP 哀求和相应举行拦截和处理处罚。但是,它们的工作原理和应用场景有所差别。
                        特性
                       
                        拦截器 (Interceptor)
                       
                        过滤器 (Filter)
                       
                        生命周期
                       
                        只在 SpringMVC 生命周期内起作用
                       
                        可以跨多个应用,通常与 Servlet 容器干系
                       
                        实用范围
                       
                        只实用于 SpringMVC 控制器的哀求处理处罚过程
                       
                        可以处理处罚全部范例的哀求和相应
                       
                        实行时机
                       
                        在 Controller 方法调用之前和之后
                       
                        在哀求到达 Servlet 之前和相应返回之前
                       
                        是否可以大概访问 SpringMVC 的功能
                       
                        可以访问 SpringMVC 提供的各种功能
                       
                        不能直接访问 SpringMVC 的功能
                       
                        设置方式
                       
                        设置在 Spring 设置文件中
                       
                        设置在 web.xml 文件中
                       
拦截器更贴近 SpringMVC 的哀求处理处罚机制,能与 Spring 提供的功能更加精密地集成,而过滤器更多的是一种通用的 Web 组件,实用于差别范例的 Web 应用。
过滤器依赖于servlet,而拦截器技能属于SpringMVC
过滤器可对全部哀求起作用,拦截器只对访问controller层的哀求起作用。
过滤器会比拦截器先实行。拦截器(Interceptor)是在Servlet和Controller控制器之间实行;而过滤器(Filter)是在哀求进入Tomcat容器之后 但是在哀求进入Servlet之前实行。

 
三、拦截器的工作时机

1、三个阶段

预处理处罚阶段:在哀求到达 Controller 之前,拦截器的 preHandle() 方法会被实行。
后处理处罚阶段:在 Controller 方法实行后,视图渲染之前,拦截器的 postHandle() 方法会被调用。
终极处理处罚阶段:无论哀求乐成与否,拦截器的 afterCompletion() 方法都会在哀求竣事时实行。
2、三个常用方法

都在接口HandlerInterceptor中声明。
1.preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

在 Controller 方法实行之前调用。返回值是 boolean 范例,true 表现继续实行,false 表现哀求被中断,后续的拦截器和 Controller 不会实行。
2. postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)

在 Controller 方法实行后,视图渲染前调用。可以对 ModelAndView 举行修改。
3. afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

在哀求处理处罚完成后(视图渲染后)调用,用于整理资源。

 
3、多个拦截器实行

1. 哀求进入多个拦截器的 preHandle() 方法

哀求会按照拦截器的设置次序进入每个拦截器的 preHandle() 方法。
假如某个拦截器的 preHandle() 返回 false,那么哀求会被制止,后续的拦截器和 Controller 方法都不会被实行。
2. 哀求进入 Controller

假如全部拦截器的 preHandle() 都返回 true,哀求会终极进入 Controller 的目标方法。
3. 多个拦截器的 postHandle() 方法

当 Controller 方法实行完毕后,拦截器的 postHandle() 方法会按设置次序从后往前被调用。即,末了设置的拦截器的 postHandle() 会开始实行。
postHandle() 方法中的 ModelAndView 还没有被渲染,可以对它举行修改。
4. 多个拦截器的 afterCompletion() 方法

末了,拦截器的 afterCompletion() 方法会按设置次序从前去后被调用,即,第一个设置的拦截器的 afterCompletion() 会开始实行。这个方法通常用于整理工作,比如日记记载或开释资源。
4、单个拦截器和多个拦截器实行次序对比

                        阶段
                       
                        单个拦截器实行次序
                       
                        多个拦截器实行次序
                       
                        preHandle()
                       
                        按次序实行,碰到
                        false
                        制止哀求
                       
                        按次序实行,碰到
                        false
                        制止哀求
                       
                        Controller
                       
                        实行 Controller 方法
                       
                        实行 Controller 方法
                       
                        postHandle()
                       
                        按次序实行(假如有多个拦截器,从前到后)
                       
                        按设置次序反向实行(从末了一个拦截器到第一个)
                       
                        afterCompletion()
                       
                        按次序实行(从前到后)
                       
                        按设置次序正向实行(从第一个拦截器到末了一个)
                       
四、单个拦截器示例


1、创建拦截器
  1. package com.goose.config;
  2. import org.springframework.web.servlet.HandlerInterceptor;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5. public class LoginInterceptor implements HandlerInterceptor {
  6.     @Override
  7.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  8.         // 获取请求url
  9.         String url = request.getRequestURI();
  10.         // 请求是否是登录相关的请求
  11.         if(url.contains("login")){
  12.             return true;
  13.         }else{// 判断是否登录过
  14.             if(request.getSession().getAttribute("user")!=null){
  15.                 return true;
  16.             }else{
  17.                 // 重定向到login页面
  18.                 response.sendRedirect("/html/login.html");
  19.                 return false;
  20.             }
  21.         }
  22.     }
  23. }
复制代码
2、设置拦截器
  1. <!-- 配置拦截器 -->
  2. <mvc:interceptors>
  3.     <mvc:interceptor>
  4.         <mvc:mapping path="/**"/> <!--表示拦截所有请求-->
  5.         <bean class="com.goose.config.LoginInterceptor" ></bean>
  6.     </mvc:interceptor>
  7. </mvc:interceptors>
复制代码
3、在Controller 中处理处罚登录
  1. package com.goose.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RequestMethod;
  5. import javax.servlet.http.HttpSession;
  6. @Controller
  7. @RequestMapping("/login")
  8. public class LoginController {
  9.     @RequestMapping("/toLogin")
  10.     public String toLogin(){
  11.         return "login";
  12.     }
  13.     @RequestMapping(value = "/login")
  14.     public String login(String username, String password, HttpSession session){
  15.         if(username.equals("张三") && password.equals("123")){
  16.             System.out.println("用户登录成功");
  17.             session.setAttribute("user","张三");
  18.             return "A";
  19.         }
  20.         return "B";
  21.     }
  22. }
复制代码
html界面略

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表