Java:SpringMVC拦截器

SpringMVC拦截器

在这里插入图片描述

1. 拦截器介绍

  • SpringMVC提供的拦截器类似于Servlet-api中的过滤器
  • 可以对进入控制器的请求进行拦截实现相关的预处理
  • 可以对控制器的响应进行拦截实现相关的相关后处理
  • 将拦截器按照一定的顺序联结成一条链,这条链称为拦截器链(InterceptorChain)。在访问被拦截的方法和字段时,拦截器就会按照其之前定义的顺序被调用
  • 拦截器是AOP思想的具体应用

1.1 拦截器实现的接口

拦截器实现HandlerInterceptor接口

HandlerInterceptor接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。

  • HandlerInterceptor中的三个方法:
方法名说明
preHandle()方法将在请求处理之前进行调用,如果返回true就执行下一个拦截器,如果为false就不执行下一个拦截器。
postHandle()在请求处理方法执行后才被调用,前提是preHandle()方法返回true。它会在DispatcherServlet进行视图返回渲染之前调用,所以我们可以在这个方法中对controller处理之后的ModelAndView对象进行操作。
afterCompletion() 在整个请求结束后执行,做清理工作,前提是preHandle()返回值为true
  • 拦截器执行顺序

    如果有多个拦截器,则在xml里配置在前的先执行,配置在后的后执行。

    拦截器中方法执行顺序是:preHandle()—>目标资源—->postHandle()——>afterCompletion()

1.2 拦截器与过滤器的区别

区别过滤器Filter拦截器
使用范围是Servlet规范的一部分,所有的web项目都可以使用是springmvc框架自己的,只有使用 了springmvc框架的工程才能用。
拦截范围在url-pattern中配置了/*后,可以对所有要访问的资源进行拦截只会拦截访问的控制器方法,如果访问的是jsp,html,css,image或者js是不会拦截的
配置文件 web.xmlSpringMVC配置文件spring-servt.xml

在这里插入图片描述

在这里插入图片描述

2. 自定义拦截器

创建拦截器类实现 HandlerInterceptor接口
②在springMVC配置文件配置拦截器
③测试拦截器的拦截效果

2.1 创建拦截器

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

在这里插入图片描述

2.2 配置拦截器

在spring-servlet.xml配置拦截器

在这里插入图片描述

<!--配置拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <!-- /**可以拦截路径不管多少层 -->
        <mvc:mapping path="/**"/>
        <bean id="loginInterceptor" class="com.xiaoqing.LoginInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

3. 拦截器控制用户授权访问案例

案例:模拟用户登录和注销功能,用户只能访问登录页面,登录成功才能访问欢迎页面,否则访问不了

(此案例没有密码验证功能,只需要提供用户名密码就可以登陆,主要验证未授权访问)

  • 创建用户登录页面和欢迎页面,将页面放在webapp/WEB-INF/jsp中,这些才能实现通过控制器的方法访问而不是直接访问
  • 登陆页面提交表单的登陆信息。需要在controller中处理。
  • 拦截用户请求,判断用户是否登陆。如果用户已经登陆。放行, 如果用户未登陆,跳转到登陆页面

流程图:

  • 未配置拦截器前:

在这里插入图片描述

  • 配置拦截器后

在这里插入图片描述

3.1 WEB-INF目录下资源的访问

  • WEB-INF目录下的资源浏览器不能直接访问,需要访问controller方法,由方法通过视图解析器的解析才能访问WEB-INF下的资源
  • 与前端控制器不同的是,在前端控制器配置那里,我们在web.xml里配置了拦截所有的客户端请求,统一交由前端控制器dispatcherServlet来处理,如果访问的是对应的controller方法,则交由controller方法处理,如果是静态资源,则交由tomcat默认的servlet来处理。

在这里插入图片描述

​ 通过上面的图片可知webapp下面包括css,imgs等资源和WEB-INF目录。除了WEB-INF下面的资源,其他的都可以在浏览器输入特定的地址来访问。WEB-INF则必须由controller经视图解析器解析后来访问

在这里插入图片描述

3.2 创建首页面

webapp下创建index.jsp

在这里插入图片描述

<%--
  Created by IntelliJ IDEA.
  User: c
  Date: 2023/1/8
  Time: 0:30
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/login.css">
    <title>Document</title>
</head>
<body>
    <form class="login">
      <p>Index</p>
      <p><a href="${pageContext.request.contextPath}/user/loginPage">登陆页面</a></p>
      <p><a href="${pageContext.request.contextPath}/user/successPage">欢迎页面</a></li>
    </form>
</body>
</html>

3.3 创建登录页面和欢迎页面

webapp/WEB-INF下创建login.jspsuccess.jsp

WEB-INF下的jsp不能通过浏览器直接访问,需要通过controller方法访问

  • login.jsp

在这里插入图片描述

<%--
  Created by IntelliJ IDEA.
  User: c
  Date: 2023/1/8
  Time: 0:16
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/login.css">
    <title>Document</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/user/login" method="post" class="login">
        <p>Login</p>
        <input type="text" placeholder="用户名" name="username">
        <input type="password" placeholder="密码" name="password">
        <input type="submit" class="btn" value="登  录">
    </form>
</body>
</html>
  • success.jsp

在这里插入图片描述

<%--
  Created by IntelliJ IDEA.
  User: c
  Date: 2023/1/8
  Time: 0:24
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/login.css">
    <title>Document</title>
</head>
<body>
    <form class="login">
        <p>Welcome</p>
        <p>欢迎${username}!!!</p>
        <h3><a href="${pageContext.request.contextPath}/user/logout">注销登陆</a></h3>
    </form>
</body>
</html>

3.4 创建控制器类

创建UserController,处理和响应用户请求

  • UserController

在这里插入图片描述
在这里插入图片描述

@Controller
@RequestMapping("/user")
public class UserController {
    //跳转到登陆页面
    @RequestMapping("/loginPage")
    public String loginPage(){
        System.out.println("---------登陆页面");
        return "login";
    }
    //跳转到欢迎页面
    @RequestMapping("/successPage")
    public String successPage(){
        System.out.println("---------欢迎页面");
        return "success";
    }
    //用户登陆
    @RequestMapping("/login")
    public String login(String username, String password, HttpSession session){
        System.out.println("---------用户登陆");
        System.out.println("username:" + username);
        System.out.println("password:" + password);
        //向session中传值
        session.setAttribute("username",username);
        return "success";
    }
    //用户注销
    @RequestMapping("/logout")
    public String logout(HttpSession session){
        System.out.println("---------用户注销");
        //设置session过期
        session.invalidate();
        return "login";
    }
}

3.5 配置视图解析器

spring-servlet.xml配置视图解析器

在这里插入图片描述

<!--配置视图解析器器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/"/>
    <property name="suffix" value=".jsp"/>
</bean>

3.6 程序测试(未配置拦截器之前)

(1)首页面-登陆页面-提交登陆信息(tom 123456)-欢迎页面

在这里插入图片描述

(2)未退出浏览器-首页面-欢迎页面

在这里插入图片描述

(3)关闭浏览器-首页面-欢迎页面

在这里插入图片描述

测试结果:

未配置拦截器之前,未登录的用户可以访问到登陆成功才能访问到的页面

3.7 创建拦截器

创建一个拦截器,拦截用户请求,判断用户是否已经登陆,确定是否放行

在这里插入图片描述
在这里插入图片描述

public class LoginInterceptor implements HandlerInterceptor {
    //预处理
    //在执行Controller方法之前来执行的
    //用于用户认证校验、用户权限校验
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        //得到请求的url
        String url = request.getRequestURI();
        //判断是否是公开地址
        //实际开发中需要公开地址配置在配置文件中
        if(url.contains("login")){
            //如果是公开地址则放行
            return true;
        }
        //判断用户身份在session中是否存在
        HttpSession session = request.getSession();
        String username = (String) session.getAttribute("username");
        //如果用户身份在session中存在放行
        if(username != null){
            return true;
        }
        //执行到这里拦截,跳转到登陆页面,用户进行身份认证
        request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
        //如果返回false表示拦截不继续执行handler,如果返回true表示放行
        return false;
    }
    //后处理
    //在执行Controller方法之后返回modelAndView之前来执行
    //如果需要向页面提供一些公用的数据或配置一些视图信息,使用此方法实现从modelAndView入手
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        System.out.println("---------postHandle");
    }
    //完成对页面的渲染之后执行此方法
    //作系统统一异常处理,进行方法执行性能监控,在preHandle中设置一个时间点,
    // 在afterCompletion设置一个时间,两个时间点的差就是执行时长
    //实现系统统一日志记录
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                Exception ex) throws Exception {
        System.out.println("---------afterCompletion");
    }
}

3.8 配置拦截器

spring-servlet.xml配置拦截器

在这里插入图片描述

<!--配置拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <!-- /**可以拦截路径不管多少层 -->
        <mvc:mapping path="/**"/>
        <bean id="loginInterceptor" class="com.xiaoqing.LoginInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

3.9 程序测试(配置拦截器之后)

(1)首页面-登陆页面(提交登陆数据tom 123456)-欢迎页面

在这里插入图片描述

(2)未退出浏览器-首页面-欢迎页面

在这里插入图片描述

(3)注销用户-首页面-欢迎页面(跳转到登陆页面)

在这里插入图片描述

(4)退出浏览器-首页面-欢迎页面(跳转到登陆页面)

在这里插入图片描述

测试结果:
用户在已登陆的情况下可以访问到欢迎页面,如果未登陆、注销、退出浏览器不能访问到欢迎页面

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring MVC 拦截器(Interceptor)是一种强大的机制,它可以拦截客户端请求并在控制器处理请求之前或之后执行一些操作。拦截器可以用于许多用例,例如身份验证、日志记录、性能监视、跨站点请求伪造(CSRF)防护等。 在 Spring MVC 中,拦截器是基于 Java 的接口 org.springframework.web.servlet.HandlerInterceptor 实现的。此接口定义了三个方法,它们是: - preHandle(): 在控制器处理请求之前调用,返回值为布尔类型。如果该方法返回 true,则继续执行后续拦截器或者控制器处理请求;如果该方法返回 false,则停止执行后续拦截器或者控制器处理请求。 - postHandle(): 在控制器处理请求之后、视图呈现之前调用。可以通过该方法修改 ModelAndView 中的模型数据或者视图。 - afterCompletion(): 在视图呈现之后调用,用于清理资源。 要使用拦截器,需要在 Spring MVC 配置文件中进行配置。可以通过 <mvc:interceptors> 标签或者实现 WebMvcConfigurer 接口进行配置。以下是一个拦截器的示例代码: ```java public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在控制器处理请求之前执行 return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 在控制器处理请求之后、视图呈现之前执行 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 在视图呈现之后执行 } } ``` 在配置文件中进行配置: ```xml <mvc:interceptors> <bean class="com.example.MyInterceptor" /> </mvc:interceptors> ``` 这样就可以将 MyInterceptor 拦截器应用到所有的控制器中了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值