springboot listener、filter登录实战
转载自: www.javaman.cn
博客系统访问: http://175.24.198.63:9090/front/index

登录功能
1、前端页面
采用的是layui-admin框架,文中的验证码内容,请参考作者之前的验证码功能
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head><title>ds博客</title><div th:replace="common/link::header"></div><link rel="stylesheet" th:href="@{/static/layuiadmin/style/login.css}" media="all">
</head>
<body>
<div class="layadmin-user-login layadmin-user-display-show" id="LAY-user-login" style="display: none;"><div class="layadmin-user-login-main"><div class="layadmin-user-login-box layadmin-user-login-header"><h2>ds博客</h2><p>后台登录</p></div><div class="layadmin-user-login-box layadmin-user-login-body layui-form"><div class="layui-form-item"><label class="layadmin-user-login-icon layui-icon layui-icon-username" for="LAY-user-login-username"></label><input type="text" name="userName" value="test" id="LAY-user-login-username" lay-verify="required" placeholder="用户名" class="layui-input"></div><div class="layui-form-item"><label class="layadmin-user-login-icon layui-icon layui-icon-password" for="LAY-user-login-password"></label><input type="password" name="passWord" value="test" id="LAY-user-login-password" lay-verify="required" placeholder="密码" class="layui-input"></div><div class="layui-form-item"><div class="layui-row"><div class="layui-col-xs7"><label class="layadmin-user-login-icon layui-icon layui-icon-vercode"></label><input type="text" name="code" lay-verify="required" placeholder="图形验证码" class="layui-input"></div><div class="layui-col-xs5"><div style="margin-left: 10px;"><img id="codeImg" class="layadmin-user-login-codeimg"></div></div></div></div><div class="layui-form-item" style="margin-bottom: 20px;"><input type="checkbox" name="remember-me" lay-skin="primary" title="记住密码"></div><div class="layui-form-item"><button class="layui-btn layui-btn-fluid layui-bg-blue" lay-submit lay-filter="login">登 录</button></div></div></div><!-- <div class="layui-trans layadmin-user-login-footer">-->
<!-- <p>版权所有 © 2022 <a href="#" target="_blank">济南高新开发区微本地软件开发工作室</a> 鲁ICP备20002306号-1</p>-->
<!-- </div>-->
</div>
<div th:replace="common/script::footer"></div>
<script th:inline="javascript">layui.config({base: '/static/layuiadmin/' //静态资源所在路径}).extend({index: 'lib/index' //主入口模块}).use(['index', 'user'], function(){let $ = layui.$,form = layui.form;// 初始化getImgCode();form.render();//提交form.on('submit(login)', function(obj) {// 打开loadinglet loading = layer.load(0, {shade: false,time: 2 * 1000});// 禁止重复点击按钮$('.layui-btn').attr("disabled",true);//请求登入接口$.ajax({type: 'POST',url: ctx + '/login',data: obj.field,dataType: 'json',success: function(result) {if (result.code === 200) {layer.msg('登入成功', {icon: 1,time: 1000}, function(){window.location.href = '/';});} else {layer.msg(result.message);// 刷新验证码getImgCode();// 关闭loadinglayer.close(loading);// 开启点击事件$('.layui-btn').attr("disabled", false);}}});});$("#codeImg").on('click', function() {// 添加验证码getImgCode();});$(document).keydown(function (e) {if (e.keyCode === 13) {$('.layui-btn').click();}});// 解决session过期跳转到登录页并跳出iframe框架$(document).ready(function () {if (window != top) {top.location.href = location.href;}});});/*** 获取验证码*/function getImgCode() {let url = ctx + '/getImgCode';let xhr = new XMLHttpRequest();xhr.open('GET', url, true);xhr.responseType = "blob";xhr.onload = function() {if (this.status === 200) {let blob = this.response;document.getElementById("codeImg").src = window.URL.createObjectURL(blob);}}xhr.send();}
</script>
</body>
</html>
2、后端处理/login请求

通过springsecurity的.loginProcessingUrl(“/login”)处理,处理逻辑如下:
.loginProcessingUrl("/login") 用于指定处理登录操作的URL地址,而具体的验证逻辑是由 Spring Security 提供的认证过滤器链负责的。在Spring Security中,主要的认证过程是由UsernamePasswordAuthenticationFilter来完成的。
当用户提交登录表单,请求到达.loginProcessingUrl("/login")配置的URL时,UsernamePasswordAuthenticationFilter会拦截这个请求,然后进行以下主要步骤:
-
获取用户名和密码:从请求中获取用户输入的用户名和密码。
-
创建认证令牌:使用获取到的用户名和密码创建一个认证令牌(
UsernamePasswordAuthenticationToken)。 -
将认证令牌传递给认证管理器:将认证令牌传递给配置的认证管理器(
AuthenticationManager)进行认证。 -
执行认证逻辑:认证管理器会调用已配置的身份验证提供者(
AuthenticationProvider)来执行实际的身份验证逻辑。通常,会使用用户提供的用户名和密码与系统中存储的用户信息进行比对。 -
处理认证结果:认证提供者返回认证结果,如果认证成功,则将认证令牌标记为已认证,并设置用户权限等信息。如果认证失败,会抛出相应的异常。
-
处理认证成功或失败:根据认证的结果,
UsernamePasswordAuthenticationFilter将请求重定向到成功或失败的处理器,执行相应的操作,比如跳转页面或返回错误信息。
这个整个过程是由 Spring Security 提供的默认配置完成的,通常情况下,开发者只需要配置好认证管理器、用户信息服务(UserDetailsService),以及成功和失败的处理器,Spring Security 就会负责处理登录验证的整个流程。
package com.ds.core.config;import com.ds.blog.system.service.SysUserService;
import com.ds.core.security.CustomAccessDeniedHandler;
import com.ds.core.security.DefaultAuthenticationFailureHandler;
import com.ds.core.security.DefaultAuthenticationSuccessHandler;
import com.ds.core.security.filter.ValidateCodeFilter;
import net.bytebuddy.asm.Advice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests()// 放过.antMatchers("/loginPage", "/getImgCode").permitAll().antMatchers("/**/*.jpg", "/**/*.png", "/**/*.gif", "/**/*.jpeg").permitAll()// 剩下的所有的地址都是需要在认证状态下才可以访问.anyRequest().authenticated().and()// 过滤登录验证码.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)// 配置登录功能.formLogin().usernameParameter("userName").passwordParameter("passWord")// 指定指定要的登录页面.loginPage("/loginPage")// 处理认证路径的请求.loginProcessingUrl("/login").successHandler(defaultAuthenticationSuccessHandler).failureHandler(defaultAuthenticationFailureHandler).and().exceptionHandling().accessDeniedHandler(accessDeniedHandler).and()// 登出.logout().invalidateHttpSession(true).deleteCookies("remember-me").logoutUrl("/logout").logoutSuccessUrl("/loginPage").and().rememberMe()// 有效期7天.tokenValiditySeconds(3600 * 24 * 7)// 开启记住我功能.rememberMeParameter("remember-me").and()//禁用csrf.csrf().disable()// header response的X-Frame-Options属性设置为SAMEORIGIN.headers().frameOptions().sameOrigin().and()// 配置session管理.sessionManagement()//session失效默认的跳转地址.invalidSessionUrl("/loginPage");}
}
3、登录成功监听器(记录登录日志)
创建监听器,在登录成功的时候记录登录日志。
-
@Slf4j:
@Slf4j是 Lombok 提供的注解,用于自动生成日志对象,这里是为了方便使用日志。
-
@Component:
@Component注解将类标识为一个 Spring 组件,使得 Spring 能够自动扫描并将其纳入容器管理。
-
AuthenticationSuccessListener 实现 ApplicationListener 接口:
AuthenticationSuccessListener类实现了ApplicationListener<AuthenticationSuccessEvent>接口,表明它是一个事件监听器,监听的是用户认证成功的事件。
-
SysLoginLogService 注入:
SysLoginLogService是一个服务类,通过@Autowired注解注入到当前类中。该服务类用于对登录日志的持久化操作。
-
onApplicationEvent 方法:
onApplicationEvent方法是实现ApplicationListener接口的回调方法,在用户认证成功的时候会被触发。- 通过
authenticationSuccessEvent.getAuthentication().getPrincipal()获取登录的用户信息,这里假设用户信息是User类型。 - 通过
ServletUtil.getClientIP获取客户端的IP地址,这里使用了ServletUtil工具类,可以通过请求上下文获取IP地址。 - 创建一个
SysLoginLog对象,将登录成功的相关信息设置进去,包括账号、登录IP、备注等。 - 调用
sysLoginLogService.save(sysLoginLog)将登录日志持久化存储。
总的来说,这段代码的作用是在用户成功登录后,通过监听 Spring Security 的认证成功事件,记录用户的登录日志信息,包括登录账号、登录IP和登录成功的备注。这样可以实现登录成功后的自定义操作,例如记录登录日志等。
@Slf4j
@Component
public class AuthenticationSuccessListener implements ApplicationListener<AuthenticationSuccessEvent> {@Autowiredprivate SysLoginLogService sysLoginLogService;@Overridepublic void onApplicationEvent(AuthenticationSuccessEvent authenticationSuccessEvent) {// 登录账号User user = (User) authenticationSuccessEvent.getAuthentication().getPrincipal();// 请求IPString ip = ServletUtil.getClientIP(((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(), "");SysLoginLog sysLoginLog = new SysLoginLog();sysLoginLog.setAccount(user.getUsername());sysLoginLog.setLoginIp(ip);sysLoginLog.setRemark("登录成功");sysLoginLogService.save(sysLoginLog);}
}
4、登录失败监听器(记录登录日志)
创建监听器,在登录失败的时候记录异常登录日志。
@Slf4j
@Component
public class AuthenticationFailureListener implements ApplicationListener<AbstractAuthenticationFailureEvent> {@Autowiredprivate SysLoginLogService sysLoginLogService;@Overridepublic void onApplicationEvent(AbstractAuthenticationFailureEvent abstractAuthenticationFailureEvent) {// 登录账号String username = abstractAuthenticationFailureEvent.getAuthentication().getPrincipal().toString();// 登录失败原因String message ;if (abstractAuthenticationFailureEvent instanceof AuthenticationFailureBadCredentialsEvent) {//提供的凭据是错误的,用户名或者密码错误message = "提供的凭据是错误的,用户名或者密码错误";} else if (abstractAuthenticationFailureEvent instanceof AuthenticationFailureCredentialsExpiredEvent) {//验证通过,但是密码过期message = "验证通过,但是密码过期";} else if (abstractAuthenticationFailureEvent instanceof AuthenticationFailureDisabledEvent) {//验证过了但是账户被禁用message = "验证过了但是账户被禁用";} else if (abstractAuthenticationFailureEvent instanceof AuthenticationFailureExpiredEvent) {//验证通过了,但是账号已经过期message = "验证通过了,但是账号已经过期";} else if (abstractAuthenticationFailureEvent instanceof AuthenticationFailureLockedEvent) {//账户被锁定message = "账户被锁定";} else if (abstractAuthenticationFailureEvent instanceof AuthenticationFailureProviderNotFoundEvent) {//配置错误,没有合适的AuthenticationProvider来处理登录验证message = "配置错误";} else if (abstractAuthenticationFailureEvent instanceof AuthenticationFailureProxyUntrustedEvent) {// 代理不受信任,用于Oauth、CAS这类三方验证的情形,多属于配置错误message = "代理不受信任";} else if (abstractAuthenticationFailureEvent instanceof AuthenticationFailureServiceExceptionEvent) {// 其他任何在AuthenticationManager中内部发生的异常都会被封装成此类message = "内部发生的异常";} else {message = "其他未知错误";}// 请求IPString ip = ServletUtil.getClientIP(((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(), "");SysLoginLog sysLoginLog = new SysLoginLog();sysLoginLog.setAccount(username);sysLoginLog.setLoginIp(ip);sysLoginLog.setRemark(message);sysLoginLogService.save(sysLoginLog);}
}
5、认证成功处理器
下面是一个认证成功处理器,登录成功后,会返回响应的信息给前端
@Component
@Slf4j
public class DefaultAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {log.info("-----login in success----");response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();writer.write(JSON.toJSONString(Result.success()));writer.flush();}
}
.successHandler(defaultAuthenticationSuccessHandler)
.failureHandler(defaultAuthenticationFailureHandler)
6、认证失败处理器
下面是一个认证成功处理器,登录成功后,会返回响应的信息给前端
@Component
@Slf4j
public class DefaultAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {log.info("login in failure : " + exception.getMessage());response.setContentType("application/json;charset=utf-8");response.setCharacterEncoding("utf-8");PrintWriter writer = response.getWriter();String message;if (exception instanceof BadCredentialsException) {message = "用户名或密码错误,请重试。";writer.write(JSON.toJSONString(Result.failure(message)));}else{writer.write(JSON.toJSONString(Result.failure(exception.getMessage())));}writer.flush();}
.successHandler(defaultAuthenticationSuccessHandler)
.failureHandler(defaultAuthenticationFailureHandler)
7、前端页面
返回200,就代表成功,跳转到/请求,进去index或者main页面
if (result.code === 200) {layer.msg('登入成功', {icon: 1,time: 1000}, function(){window.location.href = '/';});
} else {

总结
AuthenticationSuccessEvent 是 Spring Security 中用于表示用户认证成功的事件。判断登录成功的主要依据是在认证过程中,用户提供的凭据(通常是用户名和密码)与系统中存储的凭据匹配。以下是判断登录成功的基本流程:
- 用户提交登录表单:
- 用户在浏览器中输入用户名和密码,然后点击登录按钮,提交登录表单。
- Spring Security 拦截登录请求:
- 配置的
.loginProcessingUrl("/login")指定了登录请求的URL,Spring Security会拦截这个URL的请求。
- 配置的
- UsernamePasswordAuthenticationFilter处理登录请求:
UsernamePasswordAuthenticationFilter是 Spring Security 内置的过滤器之一,用于处理用户名密码登录认证。- 当用户提交登录表单时,
UsernamePasswordAuthenticationFilter会拦截该请求,尝试进行身份验证。
- AuthenticationManager执行身份验证:
UsernamePasswordAuthenticationFilter将用户名密码等信息封装成一个UsernamePasswordAuthenticationToken。- 通过
AuthenticationManager进行身份验证,AuthenticationManager是一个接口,实际的实现为ProviderManager。 ProviderManager通过配置的AuthenticationProvider来执行实际的身份验证逻辑。
- AuthenticationProvider处理身份验证:
DaoAuthenticationProvider是AuthenticationProvider的默认实现之一,用于处理基于数据库的身份验证。DaoAuthenticationProvider会从配置的UserDetailsService中获取用户信息,然后与用户提交的信息进行比对。
- 认证成功:
- 如果认证成功,
AuthenticationProvider会返回一个已认证的Authentication对象。 - 这个已认证的
Authentication对象包含了用户的信息,通常是UserDetails的实现。
- 如果认证成功,
- AuthenticationSuccessHandler处理认证成功:
- 在配置中,通过
.successHandler()方法指定了处理认证成功的AuthenticationSuccessHandler。 - 在这个处理器中,可以执行一些额外的逻辑,例如记录登录日志等。
- 在配置中,通过
- AuthenticationSuccessEvent被发布:
- 在处理成功的阶段,Spring Security 发布了
AuthenticationSuccessEvent事件,表示认证成功。
- 在处理成功的阶段,Spring Security 发布了
在上述流程中,认证成功的判断主要是在 AuthenticationProvider 中完成的。DaoAuthenticationProvider 会检查用户提供的密码与数据库中存储的密码是否匹配。如果匹配,就认为认证成功。当认证成功后,后续的处理流程包括 AuthenticationSuccessHandler 的执行和 AuthenticationSuccessEvent 的发布。你可以通过监听 AuthenticationSuccessEvent 事件来执行一些额外的自定义逻辑,例如记录登录日志。

相关文章:
springboot listener、filter登录实战
转载自: www.javaman.cn 博客系统访问: http://175.24.198.63:9090/front/index 登录功能 1、前端页面 采用的是layui-admin框架,文中的验证码内容,请参考作者之前的验证码功能 <!DOCTYPE html> <html lang"zh…...
【数据结构—栈的实现(数组栈)】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、栈 1.1栈的概念及结构 二、栈的实现 2.1头文件的实现—Stack.h 2.2源文件的实现—Stack.c 2.3源文件的测试—test.c 三、栈的实际测试数据展示 3.1正常的出…...
Linux安装Halo(个人网站)
项目简介 1.代码开源:Halo 的项目代码开源在 GitHub 上且处于积极维护状态,截止目前已经发布了 109 个版本。你也可以在上面提交你的问题或者参与代码贡献。2.易于部署:推荐使用 Docker 的方式部署 Halo,便于升级,同时避免了各种环境依赖的问…...
Java - Spring中Bean的循环依赖问题
什么是Bean的循环依赖 A对象中有B属性。B对象中有A属性。这就是循环依赖。我依赖你,你也依赖我。 比如:丈夫类Husband,妻子类Wife。Husband中有Wife的引用。Wife中有Husband的引用。 Spring解决循环依赖的机理 Spring为什么可以解决set s…...
使用 Python 实现简单的爬虫框架
爬虫是一种自动获取网页内容的程序,它可以帮助我们从网络上快速收集大量信息。在本文中,我们将学习如何使用 Python 编写一个简单的爬虫框架。 一、请求网页 首先,我们需要请求网页内容。我们可以使用 Python 的 requests 库来发送 HTTP 请…...
Activiti七大接口,28张表详解
Activiti七大接口,28张表详解 7大接口 RepositoryService:提供管理流程部署和流程定义API。 RuntimeService:提供运行时流程实例进行管理与控制API。 TaskService:提供流程任务管理API。 IdentityService:提供对流程…...
解决msvcr120.dll文件丢失问题
项目场景: 在VMware虚拟机中安装win7家庭版系统,安装MySQL数据库,部署项目文件。 问题描述 安装MySQL数据库过程中提示“msvcr120.dll文件丢失”。 原因分析: 提示丢失msvcr120.dll文件,我们首先要到C:\Windows\Sys…...
AI日报:人工智能与新材料的发现
文章目录 总览人工智能正在革命性地发现新的或更强的材料,这将改变制造业。更坚韧的合金问题研究解决方案 新材料人工智能存在的挑战方法探索 日本的研究人员正在使用人工智能制造更强的金属合金或发现新材料,并彻底改变制造过程 总览 日本的研究人员开…...
鱼fish数据集VOC+yolo-1400张(labelImg标注)
鱼类,是最古老的脊椎动物。易蓄积重金属。 部分不同染色体数目的杂交的后代依然有生育能力。它们几乎栖居于地球上所有的水生环境,从淡水的湖泊、河流到咸水的大海和大洋。 今天要介绍鱼的数据集。 数据集名称:鱼 fish 数据集格式…...
爬虫解析-BeautifulSoup-bs4(七)
目录 1.bs4的安装 2.bs4的语法 (1)查找节点 (2)查找结点信息 3.bs4的操作 (1)对本地文件进行操作 (2)对服务器响应文件进行操作 4.实战 beautifulsoup:和lxml一样…...
分类预测 | Matlab实现OOA-SVM鱼鹰算法优化支持向量机的多变量输入数据分类预测
分类预测 | Matlab实现OOA-SVM鱼鹰算法优化支持向量机的多变量输入数据分类预测 目录 分类预测 | Matlab实现OOA-SVM鱼鹰算法优化支持向量机的多变量输入数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现OOA-SVM鱼鹰算法优化支持向量机的多变量输…...
2.vue学习笔记(目录结构+模板语法+属性绑定)
文章目录 1.目录结构2.模板语法2.1.文本插值2.2.使用JavaScript表达式2.3.原始HTML 3.属性绑定3.1.简写3.2.布尔型Attribute3.3.动态绑定多个值 1.目录结构 1.vscode ——VSCode工具的配置文件夹 2.node_modules ——Vue项目的运行依赖文件夹 3.public ——资源文件夹&am…...
Python基本语法及高级特性总结
1. Python基本语法 1.1 变量和数据类型 在Python中,变量不需要预先声明,可以直接赋值。Python是一种动态类型语言,变量的类型会根据赋值的对象自动确定。例如: a 10 # a是整数类型变量 b 3.14 # b是浮点数类型变量 c …...
03-详解网关的过滤器工厂和常见的网关过滤器路由过滤器,默认过滤器,全局过滤器的执行顺序
过滤器工厂 过滤器种类 GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务响应的结果做加工处理 Spring提供了31中不同的路由过滤器工厂 AddResponseHeader表示给请求添加响应头 default-filters: # 默认过滤器 - AddResponseHeaderX-Response-Default-R…...
基于SSM的小儿肺炎知识管理系统设计与实现
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…...
HuffMan tree
定义 给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。 基础知识 路…...
各地加速“双碳”落地,数字能源供应商怎么选?
作者 | 曾响铃 文 | 响铃说 随着我国力争2030年前实现“碳达峰”、2060年前实现“碳中和”的“双碳”目标提出,为各地区、各行业的低碳转型和绿色可持续发展制定“倒计时”时间表,一场围绕“数字能源”、“智慧能源”、“新能源”等关键词的创新探索进…...
19.java绘图
A.Graphics类 Graphics类是java.awt包中的一个类,它用于在图形用户界面(GUI)或其他图形应用程序中进行绘制。该类通常与Component的paint方法一起使用,以在组件上进行绘制操作。 一些Graphics类的常见用法和方法: 在组…...
提升工作效率,尽在Microsoft Office LTSC 2021 for Mac!
在当今的办公环境中,高效率的工作是每个人都追求的目标。作为全球领先的办公软件套装,Microsoft Office LTSC 2021 for Mac将为您提供一站式的解决方案,帮助您轻松应对各种工作任务。 首先,Microsoft Office LTSC 2021 for Mac拥…...
day24_java的反射机制
反射 一、反射的概念 反射:加载类,反射出类的各个组成部分(类的成员:构造方法,属性,方法) java反射机制:在运行状态中,对于任何一个类都能够知道这个类的所有属性和方…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
