【SpringMVC】拦截器,实现小型登录验证

拦截器

概述

SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。

过滤器与拦截器的区别: 拦截器是AOP思想的具体应用。

过滤器

  • servlet规范中的一部分,任何java web工程都可以使用
  • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截

拦截器

  • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
  • 拦截器只会拦截访问的控制器(Controller)方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的

自定义拦截器

那如何实现拦截器呢?

想要自定义拦截器,必须实现 HandlerInterceptor 接口。

  1. 新建一个Moudule , springmvc-07-Interceptor , 添加web支持
  2. 配置web.xml 和 springmvc-servlet.xml 文件
  3. 编写一个拦截器
java 复制代码
package com.demo.interceptor;

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

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

public class MyInterceptor implements HandlerInterceptor {

    // 在请求处理的方法之前执行
    // return ture 放行,执行下一个拦截器;
    // return false 拦截,不执行下一个拦截器,也不执行控制器方法
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("------------处理前------------");
        return true;
    }

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

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("------------处理完成 清理------------");
    }
}
  1. 在springmvc的配置文件中配置拦截器,进行mcv的配置
xml 复制代码
<!--关于拦截器的配置-->
<mvc:interceptors>
  <mvc:interceptor>
    <!--/** 包括路径及其子路径-->
    <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
    <!--/admin/** 拦截的是/admin/下的所有-->
    <mvc:mapping path="/**"/>
    <!--bean配置的就是拦截器-->
    <bean class="com.kuang.interceptor.MyInterceptor"/>
  </mvc:interceptor>
</mvc:interceptors>
  1. 编写一个Controller,接收请求
java 复制代码
package com.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @RequestMapping("/t1")
    public String test() {

         System.out.println("t1被访问了...");
        return "success";
    }
}
  1. 前端 link
  1. 启动tomcat 测试一下!

验证用户是否登录 (认证用户)

实现思路
  1. 有一个登陆页面,需要写一个控制器(controller)访问页面。
  2. 登陆页面有一提交表单的动作。需要在controller中处理。判断用户名、密码 是否正确。如果正确,向session中写入用户信息。返回登陆成功 的响应页面
  3. 拦截用户请求,判断用户是否登陆。如果用户已经登陆。放行, 如果用户未登陆,跳转到登陆页面
登录逻辑验证如下:

实现代码仅实现拦截器内容。

实现过程
  1. 编写一个登陆页面 login.jsp
html 复制代码
<html>
<head>
    <title>login page</title>
</head>
<body>

<form action="${pageContext.request.contextPath}/user/login" method="post">
    用户名:<input type="text" name="name"><br/>
    密码:<input type="password" name="pwd"><br/>
    <input type="submit" value="登录">
</form>

</body>
</html>
  1. 编写一个Controller处理请求
java 复制代码
package com.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/user")
public class LoginController {

    @RequestMapping("/jumplogin")
    public String toLogin() {
        return "login";
    }

    @RequestMapping("/login")
    public String login(HttpSession session, String name, String pwd) {

        System.out.println("name-->" + name);
        System.out.println("session Before-->" + session.getAttribute("name"));

        session.setAttribute("name", name);

        System.out.println("session After-->" + session.getAttribute("name"));

        return "main";
    }

    @RequestMapping("/main")
    public String main1(HttpSession session) {
        System.out.println(session.getAttribute("name"));
        // 判断session是否过期,过期则跳转到登陆页面
        if (session.getAttribute("name") == null) {
            return "redirect:/user/toLogin";
        }
        return "main";
    }

    @RequestMapping("/logout")
    public String logout(HttpSession session) {
        // session 过期注销
        session.invalidate();
        return "login";
    }
}
  1. 编写一个登陆成功的页面 main.jsp
html 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录成功</title>
</head>
<body>

<h1>登录成功</h1>
<a href="/index.jsp">返回首页</a>

<h2>username : ${name}</h2>
</body>
</html>
  1. 在 index 页面上测试跳转!启动Tomcat 测试,未登录也可以进入主页!
html 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Interceptor</title>
</head>
<body>
<h1>Interceptor</h1>
<h2>
    <a href="${pageContext.request.contextPath}/user/main">main</a>
</h2>
<h2>
    <a href="${pageContext.request.contextPath}/user/jumplogin">login</a>
</h2>
<h2>
    <a href="${pageContext.request.contextPath}/user/logout">logout</a>
</h2>
</body>
</html>
  1. 编写用户登录拦截器
java 复制代码
package com.demo.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;

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

public class UserInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {

        System.out.println("uri: " + request.getRequestURI());
        System.out.println(request.getRequestURL().toString());

        if (request.getRequestURI().contains("login")) {
            System.out.println(" 包含 logic ");
            return true;
        }

        HttpSession session = request.getSession();

        if (session.getAttribute("name") != null) {
            return true;
        }

        System.out.println("stop logic");
        // 用户没有登陆跳转到登陆页面
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
        return false;
    }
}

这里使用request.getRequestURI()URI是统一资源标识符,只标识资源身份,不强制要求包含访问方法;URL是统一资源定位符,会标识协议,端口等内容。

  1. 在Springmvc的配置文件中注册拦截器
xml 复制代码
    <!--    拦截器配置-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--
              **:代表所有文件夹,所有请求;      包括这个请求在内的 所有请求都会拦截
              *: 代表当前目录下文件,当前请求
              -->
            <mvc:mapping path="/**"/>
            <bean class="com.demo.interceptor.MyInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/user/**"/>
            <bean class="com.demo.interceptor.UserInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
  1. 再次重启Tomcat测试!
测试
  1. 主页 --> 登录 --> 登陆成功--> 主页-->登陆成功
  1. 主页 -->++登陆成功 --> 登录++ --> 登录成功 --> 主页 --> 登出 --> 主页 --> 登录成功页面 --> 登录
相关推荐
葫芦和十三20 分钟前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp1 小时前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑1 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯2 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan4 小时前
多Agent之间的区别
后端
青石路6 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充6 小时前
1.面向对象设计思想
后端
IT_陈寒7 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro7 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端
要阿尔卑斯吗7 小时前
提示词优化启示:为什么“按顺序输出“比“关键度评分“更有效
后端