• 验证拦截器的执行流程



    活动地址:CSDN21天学习挑战赛

    目录

     单个拦截器的执行流程

    多个拦截器的执行流程 

     应用案例——用户登录权限验证


     单个拦截器的执行流程

      如果在项目中只定义了一个拦截器,那么该拦截器在程序中的执行流程如图所示。

     1.在eclipse中创建动态web项目,将Spring MVC依赖的包复制到lib目录下,如下图:

     2.在web.xml中配置Spring MVC的前端过滤器和初始化加载配置文件等信息

    1. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
    4. http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. id="WebApp_ID" version="4.0">
    6. <servlet>
    7. <servlet-name>springmvcservlet-name>
    8. <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    9. <init-param>
    10. <param-name>contextConfigLocationparam-name>
    11. <param-value>classpath:springmvc-config.xmlparam-value>
    12. init-param>
    13. <load-on-startup>1load-on-startup>
    14. servlet>
    15. <servlet-mapping>
    16. <servlet-name>springmvcservlet-name>
    17. <url-pattern>/url-pattern>
    18. servlet-mapping>
    19. web-app>

     3.在src目录下创建一个controller包,并在包中创建控制器类HelloController类

    1. package controller;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.web.bind.annotation.RequestMapping;
    4. @Controller
    5. public class HelloController {
    6. @RequestMapping("/hello")
    7. public String hello(){
    8. System.out.println("Hello");
    9. return "success";
    10. }
    11. }

     4.在src目录下创建interceptor包,在包内创建拦截器类UserInterceptor类。该类要实现HandlerInterceptor接口,并且在实现方法中需要编写输出语句来输出信息。

    1. package interceptor;
    2. import javax.servlet.http.HttpServletRequest;
    3. import javax.servlet.http.HttpServletResponse;
    4. import org.springframework.web.servlet.HandlerInterceptor;
    5. import org.springframework.web.servlet.ModelAndView;
    6. public class UserInterceptor implements HandlerInterceptor{
    7. @Override
    8. public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
    9. System.out.println("UserInterceptor...preHandle");
    10. //对拦截的请求放行处理
    11. return true;
    12. }
    13. @Override
    14. public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
    15. throws Exception {
    16. System.out.println("UserInterceptor...postHandle");
    17. }
    18. @Override
    19. public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
    20. throws Exception {
    21. System.out.println("UserInterceptor...afterCompletion");
    22. }
    23. }

     5.在src目录下创建并配置springmvc-config.xml

    1. <beans xmlns="http://www.springframework.org/schema/beans"
    2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xmlns:mvc="http://www.springframework.org/schema/mvc"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans
    6. http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/mvc
    8. http://www.springframework.org/schema/mvc/spring-mvc.xsd
    9. http://www.springframework.org/schema/context
    10. http://www.springframework.org/schema/context/spring-context.xsd">
    11. <context:component-scan base-package="controller" />
    12. <bean id="viewResoler"
    13. class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    14. <property name="prefix" value="/" />
    15. <property name="suffix" value=".jsp" />
    16. bean>
    17. <mvc:interceptors>
    18. <bean class="interceptor.UserInterceptor" />
    19. mvc:interceptors>
    20. beans>

     6.在webapp目录下创建success.jsp用于显示信息。

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. html>
    4. <html>
    5. <head>
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    7. <title>拦截器title>
    8. head>
    9. <body>
    10. ok,执行成功!
    11. body>
    12. html>

     7.运行结果:

    访问:localhost:8848/chapter14/hello

     控制台消息:

     由此可以看出,程序先执行了preHandle()方法,然后执行了控制器中的hello()方法,最后执行了拦截器类中的postHandle()方法和afterCompletion()方法,和前文描述一致。

    多个拦截器的执行流程 

     在大型项目中,通常会定义很多拦截器来实现不同的功能。多个拦截器的执行顺序如图所示。

     

     1.在interceptor包中创建两个拦截器类Interceptor1和Interceptor2类,在这两个类中均实现了HandlerInterceptor接口。

    1. package interceptor;
    2. import javax.servlet.http.HttpServletRequest;
    3. import javax.servlet.http.HttpServletResponse;
    4. import org.springframework.web.servlet.HandlerInterceptor;
    5. import org.springframework.web.servlet.ModelAndView;
    6. public class Interceptor1 implements HandlerInterceptor{
    7. @Override
    8. public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
    9. System.out.println("UserInterceptor1...preHandle");
    10. return true;
    11. }
    12. @Override
    13. public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
    14. throws Exception {
    15. System.out.println("UserInterceptor1...postHandle");
    16. }
    17. @Override
    18. public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
    19. throws Exception {
    20. System.out.println("UserInterceptor1...afterCompletion");
    21. }
    22. }
    1. package interceptor;
    2. import javax.servlet.http.HttpServletRequest;
    3. import javax.servlet.http.HttpServletResponse;
    4. import org.springframework.web.servlet.HandlerInterceptor;
    5. import org.springframework.web.servlet.ModelAndView;
    6. public class Interceptor2 implements HandlerInterceptor{
    7. @Override
    8. public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
    9. System.out.println("UserInterceptor2...preHandle");
    10. return true;
    11. }
    12. @Override
    13. public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
    14. throws Exception {
    15. System.out.println("UserInterceptor2...postHandle");
    16. }
    17. @Override
    18. public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
    19. throws Exception {
    20. System.out.println("UserInterceptor2...afterCompletion");
    21. }
    22. }

    2.在配置文件springmvc-config.xml文件中配置上面定义的两个拦截器

    1. <mvc:interceptor>
    2. <mvc:mapping path="/**" />
    3. <bean class="interceptor.Interceptor1" />
    4. mvc:interceptor>
    5. <mvc:interceptor>
    6. <mvc:mapping path="/hello" />
    7. <bean class="interceptor.Interceptor2" />
    8. mvc:interceptor>

     3.运行结果:

    访问:localhost:8848/chapter14/hello

     控制台消息:

     可以看出,程序先执行了两个拦截器的preHandle()方法,这两个方法的执行顺序与配置文件中定义的顺序相同;然后执行了控制器的hello()方法,然后执行了拦截器的postHandle()和afterCompletion()方法,且这两个方法的执行顺序与配置文件中所定义的拦截器顺序相反。

     应用案例——用户登录权限验证

     通过拦截器来完成一个用户登录权限验证的案例。该案例的整个执行流程如图所示。

     

     从流程图看出,只有登录后的用户才能访问管理主页,如果没有登录而直接访问主页,则拦截器会将请求拦截,并转发到登录页面,同时在登录页面中给出提示信息。如果用户名或密码错误,也会在登录页面给出相应的提示信息。当已登录的用户在管理主页中单击“退出”链接时,同样会回到登录页面。

     1.在src目录下创建po包,在包内创建User类

    1. package po;
    2. public class User {
    3. private Integer id;
    4. private String username;
    5. private String password;
    6. public Integer getId() {
    7. return id;
    8. }
    9. public void setId(Integer id) {
    10. this.id = id;
    11. }
    12. public String getUsername() {
    13. return username;
    14. }
    15. public void setUsername(String username) {
    16. this.username = username;
    17. }
    18. public String getPassword() {
    19. return password;
    20. }
    21. public void setPassword(String password) {
    22. this.password = password;
    23. }
    24. }

    2.在controller包中创建控制器类UserController,并在该类中定义向主页跳转,向登陆页面跳转。执行用户登录等操作的方法

    1. package controller;
    2. import javax.servlet.http.HttpSession;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.ui.Model;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. import org.springframework.web.bind.annotation.RequestMethod;
    7. import po.User;
    8. @Controller
    9. public class UserController {
    10. /*
    11. * 向用户登陆页面跳转
    12. */
    13. @RequestMapping(value="/toLogin",method=RequestMethod.GET)
    14. public String toLogin(){
    15. return "login";
    16. }
    17. /*
    18. * 用户登录
    19. */
    20. @RequestMapping(value="/login",method=RequestMethod.POST)
    21. public String login(User user,Model model,HttpSession session){
    22. String username=user.getUsername();
    23. String password=user.getPassword();
    24. //模拟从数据库获取用户名和密码进行判断
    25. if(username!=null && username.equals("zyy")){
    26. if(password!=null && password.equals("123456")){
    27. //用户存在,将用户信息保存到session中,并复位向到主页
    28. session.setAttribute("user_session", user);
    29. return "redirect:main";
    30. }
    31. }
    32. //用户不存在将错误信息到model中,并跳转到登陆页面
    33. model.addAttribute("msg","用户或密码输入错误,请重新登录");
    34. return "login";
    35. }
    36. /*
    37. * 向管理主页跳转
    38. */
    39. @RequestMapping(value="/main")
    40. public String toMain(){
    41. return "main";
    42. }
    43. /*
    44. * 退出
    45. */
    46. @RequestMapping(value="/logout")
    47. public String logout(HttpSession session){
    48. session.invalidate();
    49. return "redirect:toLogin";
    50. }
    51. }

    3.在interceptor包中创建拦截器类LoginInterceptor

    1. package interceptor;
    2. import javax.servlet.http.HttpServletRequest;
    3. import javax.servlet.http.HttpServletResponse;
    4. import javax.servlet.http.HttpSession;
    5. import org.springframework.web.servlet.HandlerInterceptor;
    6. import org.springframework.web.servlet.ModelAndView;
    7. import po.User;
    8. public class LoginInterceptor implements HandlerInterceptor{
    9. @Override
    10. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    11. //获取请求的URL
    12. String url=request.getRequestURI();
    13. //允许公开访问"/toLogin"
    14. if(url.indexOf("/toLogin")>=0){
    15. return true;
    16. }
    17. //允许公开访问"/Login"
    18. if(url.indexOf("/login")>=0){
    19. return true;
    20. }
    21. //获取session
    22. HttpSession session=request.getSession();
    23. User user=(User)session.getAttribute("user_session");
    24. //如果user不为空,表示已经登录
    25. if(user!=null){
    26. return true;
    27. }
    28. request.setAttribute("msg","请先登录");
    29. request.getRequestDispatcher("/login.jsp").forward(request, response);
    30. return false;
    31. }
    32. @Override
    33. public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
    34. throws Exception {
    35. }
    36. @Override
    37. public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
    38. throws Exception {
    39. }
    40. }

    4.在配置文件中配置自定义的登录拦截器信息

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

    5.在webapp目录下创建管理主页面main.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. html>
    4. <html>
    5. <head>
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    7. <title>管理主页title>
    8. head>
    9. <body>
    10. 当前用户信息:${user_session.username}
    11. <a href="${pageContext.request.contextPath}/logout">退出a>
    12. body>
    13. html>

    6.在webapp目录下创建登陆页面login.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. html>
    4. <html>
    5. <head>
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    7. <title>用户登录title>
    8. head>
    9. <body>
    10. <font style="color:Red;">${msg }font>
    11. <form action="${pageContext.request.contextPath}/login" method="post">
    12. 登录名:<input type="text" name="username" id="username" /> <br />
    13.     码:<input type="password" name="password" id="password" /> <br />
    14. <input type="submit" value="登录" />
    15. form>
    16. body>
    17. html>

    7.运行结果

    运行localhost:8848/chapter14/main

     输入正确的账号密码(zyy,123456)后会跳转到管理主页面

     如果输入错误,会提醒用户或密码输入错误

    项目源码:

    链接:https://pan.baidu.com/s/1-J6eiunkWVG7NxqSxRgO4A?pwd=r5za
    提取码:r5za

  • 相关阅读:
    Python —— 验证码的处理&执行JavaScript语句
    计算机网络 - 数据链路层 选择填空复习题
    前端周刊第十七期
    JUC-Java线程
    axios配置代理ip
    html从零开始10:注释与常见输出方式,数据类型,typeof运算符,运算符之算术、赋值、比较、布尔运算符【搬代码】
    Python编程语言学习:shap.force_plot函数的源码解读之详细攻略
    PHP8中final关键字的应用-PHP8知识详解
    C++ 之 backtrace
    C语言进阶:结构体,枚举,联合(结尾有彩蛋)
  • 原文地址:https://blog.csdn.net/weixin_52473454/article/details/126275951