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

news2025/1/18 2:10:08

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

  • 🍎一. 用户登陆统一验证功能
    • 🍒1.1 用户登录验证的几种方法
    • 🍒1.2 创建前端页面
    • 🍒1.3 创建登陆方法和欢迎进入方法
    • 🍒1.4 自定义一个拦截器
    • 🍒1.5 验证拦截功能
      • 🍉1.5.1 当没有进行登陆,进入欢迎页面
      • 🍉1.5.2 当用户未成功输入正确用户名和密码
      • 🍉1.5.3 当用户成功输入正确用户名和密码后登陆欢迎页面
      • 🍉1.5.4 使用前缀方法进行登陆
    • 🍒1.6 小结

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

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

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

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

  3. 第二版的用户登陆验证: 使用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 当没有进行登陆,进入欢迎页面

当我们在没有进行登陆时,直接输入欢迎页面时
在这里插入图片描述
我们通过重定向的方法就可以将用户引导到登陆页面中
在这里插入图片描述

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

我们会返回一个 false结果来提醒用户输入的用户名和密码错误
在这里插入图片描述

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

我们先进行用户登陆成功操作
在这里插入图片描述
再次输入欢迎页面,我们就可以看到欢迎页面的内容啦!
在这里插入图片描述

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

上文我们可以使用

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

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

🍒1.6 小结

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

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/161934.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

API--应用层之间的应用程序接口

API的前言互联网的应用特点是具有开放式的业务体系结构之一。关键的技术就是网络控制与应用层之间的应用程序接口--API。通过API接口很多问题便水到渠成&#xff0c;迎刃而解 。API到底是一种什么技术呢具有开放式的业务体系结构将是下一代网络的重要特征之一。其中&#xff0c…

干货 | APP和小程序在开发有什么区别?

随着互联网的不断进步&#xff0c;移动终端在生活中的应用也越来越多。 据工信部数据显示&#xff0c;截至2022年11月底&#xff0c;国内市场监测到的APP数量为272万款&#xff0c;其中App Store(中国区)的APP数量为136万款&#xff0c;本土第三方应用商店&#xff08;主要是安…

数据库连接池监控的另类方案

如果这篇对你有帮助&#xff0c;还请麻烦转发。谢谢。数据库的连接池的监控的重要性假如&#xff0c;我们在公有云上存在一个数据库数据库实例X。公有云配置中已经说明X所支持的最大连接数是1000。如果数据库X的实际连接数达到了1000&#xff0c;那么&#xff0c;新的连接就无法…

输入的文本就能演奏一段爵士乐? #Riffusion

riff diffusion 是 stable diffusion 的微调模型&#xff0c;以生成频谱图图像来转换音乐。能产生更精准的声音模型叫&#xff1a;Riffusion。它能对音频进行剪辑处理&#xff0c;或者是无限地修改提示符。Riffusion图源&#xff1a;riffusion 官网频谱图频谱图是音频声波的视…

【超分综述】

A comprehensive review on deep learning based remote sensing image super-resolution methods (基于深度学习的遥感图像超分辨率方法综述) 卫星图像是地球科学领域各种应用的重要地理信息源。然而&#xff0c;由于光学和传感器技术的局限性以及传感器和设备更新的高成本&…

迅为i.MX8M Mini开发板debug调试方法(Qir trl RIL驱动不工作)

可能导致 Quectel RIL 操作失败的原因有很多。一些常见的原因如下所示&#xff0c;用于故障排除。 1 输入以下命令用于检查 ril daemon 的状态。如果未返回任何值&#xff0c;或者返回了 Stopped 或 Restarting 等 值而不是 Running&#xff0c;则表明 RIL 守护进程未运行。 ge…

时序预测 | Python实现Attention-TCN注意力机制时间卷积神经网络的多元时间序列预测

时序预测 | Python实现Attention-TCN注意力机制时间卷积神经网络的多元时间序列预测 目录 时序预测 | Python实现Attention-TCN注意力机制时间卷积神经网络的多元时间序列预测预测效果基本介绍环境配置程序设计模型效果参考资料预测效果 基本介绍 使用时间注意卷积神经网络进行…

2023版大数据学习路线图(适合自学)

随着信息产业的迅猛发展&#xff0c;大数据应用逐渐落地&#xff0c;行业人才需求量逐年扩大。大数据成为目前最具前景的高薪行业之一&#xff0c;大数据分析工程师、大数据开发工程师等大数据人才也成为市场紧缺型人才&#xff0c;薪资一涨再涨。很多人想要加入到大数据开发行…

学会这几个方法,帮你轻松完成工作

方法一&#xff1a;分节 分节有比分页更体贴入微的分节功能。 “节”在word中是很重要的&#xff0c;它代表着文档中的标记。 分页只是视觉上产生了一个新页&#xff0c;分节让Word在内容上建立一个个不同的区域。 操作方法&#xff1a; 鼠标光标定位在需要分节的文档位置…

Java-Jstack-生产问题的排查死锁/泄露/cpu负载

文章目录 排查死锁jdk自带的jstack排查死锁jdk自带的jconsole排查死锁排查CPU爆满内存溢出、泄漏排查内存溢出定位 - 内存泄漏内存溢出实战排查死锁 首先如果是本地开发环境可以通过JVisualVM查看是否有长时间休眠的线程 注意:正式部署版本不会用JVisualVM,会留下漏洞jdk自带…

第一天总结之项目的搭建

第一天总结之项目的搭建&#xff1a; Mvc框架的搭建 1、创建一个javaWeb项目 创建项目 添加web支持 在Web-INF下创建 classes和lib文件夹 重构项目 配置tomcat 2、搭建 Mvc框架 在src下创建 com.edu文件夹 在其下分别创建controller dao entity filter service utils文件夹…

Clion配置openCV开发环境(Clion+MinGW+CMake+openCV)

所需资源 系统 win11(X64)MinGW-W64 GCC-8.1.0 x86_64-8.1.0-release-posix-seh.7z MinGW作用是opencv需要用到支持多线程&#xff08;posix版本&#xff09;的C编译环境。Clion-2022.3.1.exeCMake-3.25.1-windows-x86_64.msiopenCV4.6.0 安装步骤 解压ming.7z&#xff0c;安…

node.js全栈项目

一、项目介绍本项目适合作为一个课程设计或者毕业设计&#xff0c;最终实现了一个完整的博客系统&#xff0c;包括用户的登录、注册&#xff0c;图片上传&#xff0c;文章的发布、富文本编辑器、删除、编辑、修改、列表展示&#xff0c;评论的发布、删除、列表展示&#xff0c;…

K2P padavan固件下宽带与IPTV融合

一、我的需求 坐标江苏小城&#xff0c;原来手机用的99的套餐&#xff0c;可以免费带一个副卡&#xff0c;现在升级了电信129的5G融合套餐&#xff0c;送了一个iTV&#xff08;一个月10元&#xff09;&#xff0c;但是副卡收费10元&#xff0c;哎&#xff0c;算来算去都没有运营…

【软考】系统集成项目管理工程师(十三)项目干系人管理

一、项目干系人管理基础二、干系人管理子过程1. 识别干系人2. 规划干系人管理3. 管理干系人4. 控制干系人参与一、项目干系人管理基础 项目干系人管理是指对项目干系人需求、希望和期望的识别,并通过沟通上的管理来满足 其需要、解决其问题的过程。 每个项目都有干系人,他们…

雅思经验(3)

听力技巧&#xff1a;section 1错1,section 2错2,section 3错5,section 4错5,共错13题,才擦边达到6.5分。听力的关键点在于2和4&#xff0c;因为1和3的场景基本可以固定下来。剑9的section3那个Soiros同学真的很可怕&#xff0c;印度人&#xff0c;口音真的非常重&#xff0c;但…

LVGL基础部件学习笔记

目录 1、基础对象基本属性用法&#xff08;所有部件都可以用&#xff09; 1.1、基础对象的大小(Size) 1.2、基础对象的位置(Position) 1.3、基础对象对齐(Alignment) 1. 4、基础对象的盒子模型(border-box) 1.5、基础对象的样式(styles) 1.6、基础对象的事件(events) 2…

小偷与守望者.math库.动态规划.贪心.C

1.分别讨论0或1;边界 2.写出递推方程;最优子结构、状态转移方程、重叠子问题 int rob(int* arr, int size){ int dp[size];int result; if(size0)return 0; if(size1)return arr[0]; else{ dp[0]arr[0]; dp[1]arr[1] > arr[0] ? arr[1]:arr[0]; for (int i 2; i < siz…

php学习笔记-连接操作mysq数据库(基础)-day08

php学习笔记-连接操作mysq数据库-day08php中常用的mysql操作函数1.连接mysql服务器mysqli_connect()2.设置数据库字符集 和 发送sqlmysqli_query() 函数 可以用来设置数据库字符集。3.关闭mysql服务器连接mysqli_close();4.选择要操作的数据库mysqli_select_db()5.结果集释放my…

C#大型在线学习平台源码(PC端+手机端)

本套源码目录结构清晰、代码层次分明、文档齐全。源码分享&#xff01;需要源码学习可私信我获取。 系统简介 中小学教育平台是一个集学、练、考于一体的在线教育平台&#xff0c;可以帮助中小学教育机构建设网络课堂&#xff0c;用于同步课程、专题课堂、兴趣课堂等网络教育的…