当前位置:   article > 正文

SpringMVC---- SpringMVC拦截器_springmvc跳转到页面的过滤器

springmvc跳转到页面的过滤器

目录

拦截器(interceptor)的作用

拦截器和过滤器区别

拦截器快速入门

单个拦截器

多个拦截器

拦截器方法说明


拦截器(interceptor)的作用

Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。
(这个拦截器的功能相当于web阶段学习的那个filter,那么我们知道,filter是对于我们访问的目标资源进行相应的干预,比如我有个目标资源Servlet,如果你的请求地址没有写错,一般就能直接访问到目标资源,但是我们学到这个filter之后发现,即使地址没写错,你这个目标资源也不一定被访问到,因为中间有filter的过滤器,如果这个filter放行的话才能访问拿到目标资源,不放行就访问不到目标资源,这里的interceptor跟filter过滤器的功能是一样的,那么在SpringMVC技术当中,我们的目标资源就是Controller当中的一些方法,同样目前也是只要url没写错,那个方法肯定是百分之百可以被访问到。学了拦截器就知道写对了地址也不一定可以访问那个资源方法)

将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(Interceptor Chain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

拦截器也是AOP思想的具体实现。
 

拦截器和过滤器区别

区别过滤器拦截器
使用范围是 servlet 规范中的一部分,任何Java Web 工程都可以使用是 SpringMVC 框架自己的,只有使用了SpringMVC 框架的工程才能用
拦截范围在 url-pattern 中配置了/*之后,可以对所有要访问的资源拦截只会拦截访问的控制器方法,如果访问的是 jsp,html,css,image 或者 js 是不会进行拦截的

注:filter可以对所有资源进行拦截,包括静态资源,Interceptor只能对Controller中方法进行拦截,静态资源拦截不了。

拦截器快速入门

自定义拦截器很简单,只有如下三步:

1、创建拦截器类实现HandlerInterceptor接口
(实现HandlerInterceptor接口,内部有相应的方法需要我们去实现)
2、配置拦截器
(在springmvc.xml中进行配置)
3、测试拦截器的拦截效果

单个拦截器

首先来看环境,有个IndexController,就是我们要访问的目标资源,内部有个show方法,对应的虚拟地址是/text,那么现在启动这个工程,因为是没有Intercepor,最终是跳转到index.jsp,这里访问的目标方法就是这个toIndex方法,然后在返回跳转到index.jsp页面

 

那么按照前面你的步骤,我们就可以开始来实现拦截器

1、创建拦截器类实现HandlerInterceptor接口

        (这里有三个方法需要我们去重写)

  1. package com.ftp.interceptor;
  2. import org.springframework.web.servlet.HandlerInterceptor;
  3. import org.springframework.web.servlet.ModelAndView;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import java.util.logging.Handler;
  7. public class IndexInterceptor1 implements HandlerInterceptor {
  8. /**
  9. * 预处理,controller 方法执行前
  10. * return true 放行,执行下一个拦截器,如果没有,执行 controller 中的方法
  11. * return false 不放行,即不向下执行
  12. */
  13. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
  14. System.out.println("第一个拦截器");
  15. String book = request.getParameter("book");
  16. System.out.println("preHandle1 方法将在请求处理之前进行调用");
  17. /*if(book==null){
  18. System.out.println("停止1");
  19. return false;
  20. }*/
  21. return true;
  22. }
  23. /**
  24. * 后处理方法,controller 方法执行后,方法跳转 success.jsp 执行之前
  25. * 应用:从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
  26. */
  27. public void postHandle(HttpServletRequest request, HttpServletResponse
  28. response, Object handler, ModelAndView modelAndView) {
  29. System.out.println("postHandle1 该方法是在当前请求进行处理之后被调用");
  30. }
  31. /**
  32. * success.jsp 页面执行后,该方法会执行
  33. * 应用:统一异常处理,统一日志处理
  34. */
  35. public void afterCompletion(HttpServletRequest request, HttpServletResponse
  36. response, Object handler, Exception ex) {
  37. System.out.println("afterCompletion1 该方法将在整个请求结束之后");
  38. }
  39. }

2、在SpringMVC核心配置文件中配置拦截器

  1. <!--配置拦截器-->
  2. <mvc:interceptors>
  3. <!--配置拦截器,多个拦截器时,顺序执行-->
  4. <mvc:interceptor>
  5. <!--要拦截的具体的方法-->
  6. <mvc:mapping path="/*/text"/>
  7. <!--不去拦截的方法
  8. <mvc:exclude-mapping path=""/>
  9. -->
  10. <!--配置拦截器对象-->
  11. <bean class="com.ftp.interceptor.IndexInterceptor1"/>
  12. </mvc:interceptor>
  13. </mvc:interceptors>

测试拦截器的拦截效果(编写目标方法)

  1. @Controller
  2. @RequestMapping("/index")
  3. public class IndexController {
  4. @RequestMapping("/text")
  5. public String toIndex(HttpServletRequest request , HttpServletResponse response, HttpSession session){
  6. //视图解析器=前缀+逻辑视图名+后缀
  7. //前缀 /WEB-INF/jsp
  8. //逻辑视图名 index
  9. //后缀 .jsp
  10. System.out.println("controller方法一中");
  11. return "index";
  12. }
  13. }

测试拦截器的拦截效果(访问网址),控制台输出:

多个拦截器

再创建一个拦截器类实现HandlerInterceptor接口

  1. package com.ftp.interceptor;
  2. import org.springframework.web.servlet.HandlerInterceptor;
  3. import org.springframework.web.servlet.ModelAndView;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. public class IndexInterceptor2 implements HandlerInterceptor {
  7. /**
  8. * 预处理,controller 方法执行前
  9. * return true 放行,执行下一个拦截器,如果没有,执行 controller 中的方法
  10. * return false 不放行,即不向下执行
  11. */
  12. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
  13. System.out.println("第二个拦截器");
  14. String bookId = request.getParameter("bookId");
  15. System.out.println("preHandle2 方法将在请求处理之前进行调用2 ");
  16. /*if(bookId==null){
  17. System.out.println("停止2");
  18. return false;
  19. }*/
  20. return true;
  21. }
  22. /**
  23. * 后处理方法,controller 方法执行后,方法跳转 success.jsp 执行之前
  24. * 应用:从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
  25. */
  26. public void postHandle(HttpServletRequest request, HttpServletResponse
  27. response, Object handler, ModelAndView modelAndView) {
  28. System.out.println("postHandle2 该方法是在当前请求进行处理之后被调用2");
  29. }
  30. /**
  31. * success.jsp 页面执行后,该方法会执行
  32. * 应用:统一异常处理,统一日志处理
  33. */
  34. public void afterCompletion(HttpServletRequest request, HttpServletResponse
  35. response, Object handler, Exception ex) {
  36. System.out.println("afterCompletion2 该方法将在整个请求结束之后2");
  37. }
  38. }

2、在SpringMVC核心配置文件中配置多个拦截器

  1. <!--配置拦截器-->
  2. <mvc:interceptors>
  3. <!--配置拦截器,多个拦截器时,顺序执行-->
  4. <mvc:interceptor>
  5. <!--要拦截的具体的方法-->
  6. <mvc:mapping path="/*/text"/>
  7. <!--不去拦截的方法
  8. <mvc:exclude-mapping path=""/>
  9. -->
  10. <!--配置拦截器对象-->
  11. <bean class="com.ftp.interceptor.IndexInterceptor1"/>
  12. </mvc:interceptor>
  13. <mvc:interceptor>
  14. <!--要拦截的具体的方法-->
  15. <mvc:mapping path="/*/text"/>
  16. <!--不去拦截的方法
  17. <mvc:exclude-mapping path=""/>
  18. -->
  19. <!--配置拦截器对象-->
  20. <bean class="com.ftp.interceptor.IndexInterceptor2"/>
  21. </mvc:interceptor>
  22. </mvc:interceptors>

测试结果:

3.执行顺序:

=======> IndexInterceptor1:preHandle()
 =======> IndexInterceptor2:preHandle()
 .......
 =======> IndexInterceptor2:postHandle()
 =======> IndexInterceptor1:postHandle()
 =======> IndexInterceptor2:afterCompletion()
 =======> IndexInterceptor1 :afterCompletion()

拦截器方法说明

方法名说明
preHandle()   方法将在请求处理之前进行调用,该方法的返回值是布尔值Boolean类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法
postHandle()该方法是在当前请求进行处理之后被调用,前提是preHandle 方法的返回值为true 时才能被调用,且它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作
afterCompletion()该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行,前提是preHandle 方法的返回值为true 时才能被调用

自定义拦截器步骤:

        ① 创建拦截器类实现HandlerInterceptor接口

        ② 配置拦截器

        ③ 测试拦截器的拦截效果

应用场景

    1)日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。

    2)权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面;

    3)性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);

    4)通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。

登录拦截权限案例

1、LoginController.java

  1. package com.zking.ssm.book.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.ui.Model;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import javax.servlet.http.HttpSession;
  6. @Controller
  7. public class LoginController {
  8. /**
  9. * 跳转到登录页面
  10. * @return
  11. */
  12. @RequestMapping("tologin")
  13. public String toLogin(){
  14. return "login";
  15. }
  16. /**
  17. * 登录方法
  18. * @param username 账号
  19. * @param password 密码
  20. * @return
  21. */
  22. @RequestMapping("/userLogin")
  23. public String userLogin(String username, String password, HttpSession session, Model model){
  24. if("admin".equals(username)|| password.equals("123")){
  25. session.setAttribute("username",username);
  26. //这里的"/"是跳转的@RequestMapping配置的值
  27. return "redirect:/";
  28. }
  29. model.addAttribute("msg","账号或者密码错误");
  30. return "login";
  31. }
  32. /**
  33. * 安全退出
  34. * @param session
  35. * @return
  36. */
  37. @RequestMapping("/userLogout")
  38. public String userLogout(HttpSession session){
  39. //清空session
  40. session.invalidate();
  41. return "redirect:tologin";
  42. }
  43. }

2.LoginInterceptor.java

  1. package com.zking.ssm.book.interceptor;
  2. import org.springframework.web.servlet.HandlerInterceptor;
  3. import org.springframework.web.servlet.ModelAndView;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import javax.servlet.http.HttpSession;
  7. public class LoginInterceptor implements HandlerInterceptor {
  8. @Override
  9. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  10. //获取请求路径
  11. String url = request.getRequestURI();
  12. System.out.println(url);
  13. //判断是否是跳转登录页面的请求 放行
  14. if(url.indexOf("/tologin")>0)
  15. return true;
  16. //判断是否是用户登录 放行
  17. if(url.indexOf("/userLogin")>0)
  18. return true;
  19. //获取session
  20. HttpSession session = request.getSession();
  21. //获取session中的用户对象
  22. String username = (String) session.getAttribute("username");
  23. //判断session中的用户对象是否存在,存在放行,不存在跳转登录页面
  24. if(username!=null)
  25. return true;
  26. request.setAttribute("msg","您还没有登录,请登录!");
  27. request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
  28. return false;
  29. }
  30. @Override
  31. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  32. }
  33. @Override
  34. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  35. }
  36. }

spring-mvc.xml

  1. <mvc:interceptor>
  2. <mvc:mapping path="/**/"/>
  3. <bean class="com.zking.ssm.book.interceptor.LoginInterceptor"/>
  4. </mvc:interceptor>

测试:

1、账号密码错误的情况下

 2、在未登录的情况下访问首页

 3、在进入首页后退出再直接浏览首页

 

    

代码地址 提取码:c7kq

至此,SpringMVC拦截器介绍完毕,由于作者水平有限难免有疏漏,欢迎留言纠错。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/程序自动化专家/article/detail/61377
推荐阅读
相关标签
  

闽ICP备14008679号