Spring AOP【用户登陆统一验证功能】

简介: Spring AOP【用户登陆统一验证功能】

🍎一. 用户登陆统一验证功能

🍒1.1 用户登录验证的几种方法


  1. 第一版的用户登陆验证: 在每个方法里获取 session 和 session 中的用户信息,如果用户存在,那么就认为登陆成功了,否则就失败了


  1. 第二版的用户登陆验证: 提供统一的方法,在每个需要验证用户登陆的方法调用统一验证用户登陆的方法来进行判断


  1. 第二版的用户登陆验证: 使用Spring AOP 来使用统一的用户登陆检验

    遇到的问题:

● 没有办法获取到HttpSession 和 Request 对象

● 实际拦截规则很复杂,使用简单的 aspect j 表达式无法满足拦截的需求


 4.第二版的用户登陆验证: Spring 拦截器来实现用户的统一登陆验证功能


● 实现自定义拦截器 添加@Component注解,实现 Spring为我们提供的 HandlerInterceptor 接口中的 重写preHandler 方法

(一个项目中可以配置多个拦截器).

● 将自定义拦截器加入到框架的配置中去, 并且设置拦截规则如下:

(1) 给要将拦截器加入到的当前类中 叫@Configuration注解

(2) 实现 WebMvcConfigurer接口

(3) 重写 addInterceptors方法来实现需要拦截的页面,和不需要拦截的页面(白名单)


这里我们看到之前的代码里过于耦合,并且繁琐,接下来我们来学习Spring’为我们提供的框架

@RestController
@RequestMapping("/user")
public class UserController {
  /**
   * 某⽅法 1
   */
  @RequestMapping("/m1")
  public Object method(HttpServletRequest request) {
    // 有 session 就获取,没有不会创建
    HttpSession session = request.getSession(false);
    if (session != null && session.getAttribute("userinfo") != null) {
      // 说明已经登录,业务处理
      return true;
    } else {
      // 未登录
      return false;
    }
  }
  /**
   * 某⽅法 2
   */
  @RequestMapping("/m2")
  public Object method2(HttpServletRequest request) {
    // 有 session 就获取,没有不会创建
    HttpSession session = request.getSession(false);
    if (session != null && session.getAttribute("userinfo") != null) {
      // 说明已经登录,业务处理
      return true;
    } else {
      // 未登录
      return false;
    }
  }
  // 其他⽅法...
}

🍒1.2 创建前端页面

登陆页面:


<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<h1>登录页面</h1>
</body>
</html>

欢迎页面:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<h1> index 页面</h1>
</body>
</html>

🍒1.3 创建登陆方法和欢迎进入方法


package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@RequestMapping("/user")
@RestController
public class UserController {
   // 登陆页面
    @RequestMapping("/login")
    public boolean login(HttpServletRequest request,String username, String password){
        boolean result = false;
        // 判断是否在登陆页面输入账号 和 密码
        if (StringUtils.hasLength(username) && StringUtils.hasLength(password)){
            // 验证输入的账号 和 密码 是否正确
            if (username.equals("admin") && password.equals("admin")){
                // 判断输入的账号和密码正确后 建立一个 session对象进行存储
                HttpSession session = request.getSession();
                session.setAttribute("userinfo","userinfo");
                return  true;
            }
        }
        return  result;
    }
    // 欢迎页面
    @RequestMapping("/index")
    public String index() {
          return "Hello,Index";
    }


🍒1.4 自定义一个拦截器


对于以上问题 Spring 中提供了具体的实现拦截器:HandlerInterceptor,拦截器的实现分为以下两个步

骤:


  1. 创建⾃定义拦截器,实现 HandlerInterceptor 接⼝的 preHandle(执⾏具体⽅法之前的预处理)⽅法
  2. 将⾃定义拦截器加⼊实现接口 WebMvcConfigurer 类的,重写 addInterceptors ⽅法中
    具体实现如下:


一.创建⾃定义拦截器:


package com.example.demo.config;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
 *  自定义登陆用户登陆拦截器
 */
@Component
public class LoginIntercept implements HandlerInterceptor {
    /**
     * 返回 ture 表示拦截判断通过, 可以访问后面的接口, 如果返回false 表示拦截未通过,直接返回结果给前端
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
     HttpSession session =  request.getSession(false);
     if (session != null && session.getAttribute("userinfo") != null ){
         // 表示已经登陆
         return true;
     }
     // 使用重定向方法 将表示未登录,就可以使用户跳转登陆页面
        response.sendRedirect("/login.html");
     return  false;
    }
}

二.将自定义拦截器加入到框架的配置中去


package com.example.demo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
//配置存储
@Configuration
public class AppConfig implements WebMvcConfigurer {
    // 通过属性注入到拦截器
    // 通过注入拦截器来配置规则
    @Autowired
    private LoginIntercept loginIntercept;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //通过registry.addInterceptor可以得到拦截器
        // 登陆拦截 需要 通过属性注入来获取有loginIntercept拦截器对象执行拦截方法
           // addPathPatterns 是拦截方法
           // excludePathPatterns 不拦截方法是
        registry.addInterceptor(loginIntercept)
                .addPathPatterns("/**") //拦截所有 的url
                .excludePathPatterns("/user/login") //不拦截登陆
                .excludePathPatterns("/user/reg")   //不拦截注册页面
                .excludePathPatterns("/login.html") //不拦截登陆
                .excludePathPatterns("/reg.html")   //不拦截注册页面
                .excludePathPatterns("/**/*.js")    //所有的js都不拦截
                .excludePathPatterns("/**/*.css")   //所有的css都不拦截
                .excludePathPatterns("/**/*.png");  //所有的png照片都不拦截
    }
    // 给所有请求地址添加 访问页面 带有api 前缀
//    @Override
//    public void configurePathMatch(PathMatchConfigurer configurer) {
//        configurer.addPathPrefix("api",c -> true);
//    }
}


🍒1.5 验证拦截功能

🍉1.5.1 当没有进行登陆,进入欢迎页面

当我们在没有进行登陆时,直接输入欢迎页面时


4256ddf0faac417b98d6964bfe85ecbe.png

我们通过重定向的方法就可以将用户引导到登陆页面中


7300dafaee5f45c0a700b1c5793dd8a0.png


🍉1.5.2 当用户未成功输入正确用户名和密码

我们会返回一个 false结果来提醒用户输入的用户名和密码错误


01406f45441a4404a86f945ac795e5f1.png

🍉1.5.3 当用户成功输入正确用户名和密码后登陆欢迎页面

我们先进行用户登陆成功操作


4d47469e479c4f7a8ad097cfb3055811.png


再次输入欢迎页面,我们就可以看到欢迎页面的内容啦!


32246df4daef4d39a19feb1ae363d83b.png


🍉1.5.4 使用前缀方法进行登陆

上文我们可以使用

    // 给所有请求地址添加 访问页面 带有api 前缀
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.addPathPrefix("api",c -> true);
    }

d4fe32aeda3a497e96c7da7d51b8ca92.png


5c98d5733fdb4503afeed649e2904298.png


🍒1.6 小结


通过上⾯的源码分析,我们可以看出,Spring 中的拦截器也是通过动态代理和环绕通知的思想实现的,⼤体的调⽤流程如下:



6c818188604749c2b5a0daac02edebb6.png



a452ec9ed0494244976724ab4703b5b6.jpg


相关文章
|
27天前
|
XML 安全 Java
|
1月前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
61 0
|
5天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
26天前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
53 14
|
21天前
|
Java 数据库 数据安全/隐私保护
轻松掌握Spring依赖注入:打造你的登录验证系统
本文以轻松活泼的风格,带领读者走进Spring框架中的依赖注入和登录验证的世界。通过详细的步骤和代码示例,我们从DAO层的创建到Service层的实现,再到Spring配置文件的编写,最后通过测试类验证功能,一步步构建了一个简单的登录验证系统。文章不仅提供了实用的技术指导,还以口语化和生动的语言,让学习变得不再枯燥。
36 2
|
29天前
|
监控 安全 Java
什么是AOP?如何与Spring Boot一起使用?
什么是AOP?如何与Spring Boot一起使用?
56 5
|
1月前
|
Java 开发者 Spring
深入解析:Spring AOP的底层实现机制
在现代软件开发中,Spring框架的AOP(面向切面编程)功能因其能够有效分离横切关注点(如日志记录、事务管理等)而备受青睐。本文将深入探讨Spring AOP的底层原理,揭示其如何通过动态代理技术实现方法的增强。
65 8
|
1月前
|
Java 开发者 Spring
Spring AOP 底层原理技术分享
Spring AOP(面向切面编程)是Spring框架中一个强大的功能,它允许开发者在不修改业务逻辑代码的情况下,增加额外的功能,如日志记录、事务管理等。本文将深入探讨Spring AOP的底层原理,包括其核心概念、实现方式以及如何与Spring框架协同工作。
|
1月前
|
XML 监控 安全
深入调查研究Spring AOP
【11月更文挑战第15天】
46 5
|
1月前
|
Java 开发者 Spring
Spring AOP深度解析:探秘动态代理与增强逻辑
Spring框架中的AOP(Aspect-Oriented Programming,面向切面编程)功能为开发者提供了一种强大的工具,用以将横切关注点(如日志、事务管理等)与业务逻辑分离。本文将深入探讨Spring AOP的底层原理,包括动态代理机制和增强逻辑的实现。
46 4