当前位置: 首页 > news >正文

Springsecurty【2】认证连接MySQL

1.前期准备

基于Spring Initializr创建SpringBoot项目(基于SpringBoot 2.7.12版本),实现与MyBatisPlus的项目整合。分别导入:CodeGeneratorMyBatisPlusConfig

CodeGenerator:用于MybatisPlus代码生成; MyBatisPlusConfigMyBatisPlus配置类,实现了分页和乐观锁相关配置。

1.1.添加pom.xml依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope><version>5.1.44</version>
</dependency>
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.2</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.32</version>
</dependency>

1.2.配置application.yml

server:port: 8080
spring:freemarker:# 设置freemarker模板后缀suffix: .ftl# 设置freemarker模板前缀template-loader-path: classpath:/templates/enabled: true
#    security:
#        user:
#            name: admin
#            password: 123456datasource:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456url: jdbc:mysql://localhost:3306/bookshop?useUnicode=true&characterEncoding=utf8&useSSL=false

修改数据库相关账号、密码及数据库名。

1.3.导入相关数据表

将课件资料中的sql/db.sql导入到数据库中。

表名说明
sys_user用户信息表
sys_role角色信息表
sys_module模块信息表(权限信息表)
sys_user_role用户角色表
sys_role_module角色模块表

表之间的关系说明:

1.4.实现MP代码生成

直接运行CodeGenerator.java类,生成sys_开头的相关信息表。

此处省略一万字...

2.SpringSecurity之认证

2.1.导入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>

2.2.创建登录页及首页

基于freemarker模板引擎创建登录页login.ftl和首页index.ftl

login.ftl首页部分代码如下:

<h1>用户登录</h1>
<form action="/user/userLogin" method="post"><label>账号:</label><input type="text" name="username"/><br/><label>密码:</label><input type="password" name="password"/><br/><input type="submit" value="登 录"/>
</form>

index.ftl代码如下:

<h1>首页</h1>
<div style="position: absolute;top:15px;right:15px;"><a href="/logout">安全退出</a></div>

href="/logout"SpringSecurity配置的退出请求路径。主要完成以下几个操作:

  1. 清除指定 CookieCookieClearingLogoutHandler#logout

  2. 清除 remember-mePersistentTokenBasedRememberMeServices#logout

  3. 使当前 Session无效,清空当前的 SecurityContext 中认证用户信息 Authentication

2.3.创建配置Controller

创建IndexController配置跳转首页和登录页的接口。

@Controller
public class IndexController {
​@RequestMapping("/")public String toLogin(){return "login";}
​@RequestMapping("/index")public String toIndex(){return "index";}
}

UserController中配置请求登录接口:

@RestController
@RequestMapping("/user")
public class UserController {
​@RequestMapping("/userLogin")public String userLogin(User user){return "login";}}

2.4.用户认证

2.4.1.用户对象UserDetails(UserDetails用来处理前端发送的账号密码请求)

修改User并实现UserDetails

@Getter
@Setter
@TableName("sys_user")
public class User implements Serializable, UserDetails {...
​/*** 用户权限集合* @return*/@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return null;}
​/*** 用户没过期返回true,反之则false*/@Overridepublic boolean isAccountNonExpired() {return true;}/*** 用户没锁定返回true,反之则false*/@Overridepublic boolean isAccountNonLocked() {return true;}/*** 用户凭据(通常为密码)没过期返回true,反之则false*/@Overridepublic boolean isCredentialsNonExpired() {return true;}/*** 用户是启用状态返回true,反之则false*/@Overridepublic boolean isEnabled() {return true;}
}

UserDetails是Spring Security框架中的一个接口,它代表了应用程序中的用户信息。UserDetails接口定义了一组方法,用于获取用户的用户名、密码、角色和权限等信息,以便Spring Security可以使用这些信息进行身份验证和授权。

以下是UserDetails接口中定义的方法:

  • getUsername():获取用户的用户名。

  • getPassword():获取用户的密码。

  • getAuthorities():获取用户的角色和权限信息。

  • isEnabled():判断用户是否可用。

  • isAccountNonExpired():判断用户的账号是否过期。

  • isAccountNonLocked():判断用户的账号是否被锁定。

  • isCredentialsNonExpired():判断用户的凭证是否过期。

自定义用户信息时,可以实现UserDetails接口并覆盖其中的方法来提供自己的用户信息。

2.4.2.业务对象UserDetailsService

修改UserServiceImpl并实现UserDetailsService,重写loadUserByUsername(String username)方法。

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>implements UserService,UserDetailsService {
​/*** 实现Spring Security内置的UserDetailService接口,重写loadUserByUsername方法实现数据库的身份校验* @param username* @return* @throws UsernameNotFoundException*/@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//根据用户名查询数据库中用户信息User user = this.getOne(new QueryWrapper<User>().eq("username", username));//判断用户是否存在if(Objects.isNull(user))throw new UsernameNotFoundException("用户不存在");//权限校验TODO,后续讲解return user;}
}

UserDetailsService是Spring Security中的一个接口,它用于从特定数据源(如数据库)中获取用户详细信息,以进行身份验证和授权。实现该接口的类需要实现loadUserByUsername方法,该方法根据给定的用户名返回一个UserDetails对象,该对象包含有关用户的详细信息,例如密码、角色和权限等。在Spring Security中,UserDetailsService通常与DaoAuthenticationProvider一起使用,后者是一个身份验证提供程序,用于验证用户的凭据。

2.4.3.SecurityConfig配置

创建WebSecurityConfig配置类,配置SpringSecurity结合数据库方式进行身份认证和权限鉴定。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
​/*** 基于数据库方式进行身份认证和权限鉴定*/@Autowiredprivate UserDetailsService userDetailsService;/*** 配置密码编码器,首次采用明文密码方式进行比对校验*/@Beanpublic PasswordEncoder passwordEncoder(){return NoOpPasswordEncoder.getInstance();}/*** 获取AuthenticationManager(认证管理器),登录时认证使用(基于数据库方式)* @param* @return* @throws Exception*/@Beanpublic AuthenticationManager authenticationManager() throws Exception {//创建DaoAuthenticationProviderDaoAuthenticationProvider provider=new DaoAuthenticationProvider();//设置userDetailsService,基于数据库方式进行身份认证provider.setUserDetailsService(userDetailsService);//配置密码编码器provider.setPasswordEncoder(passwordEncoder());return new ProviderManager(provider);}@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
​http.authorizeRequests().antMatchers("/").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/").loginProcessingUrl("/user/userLogin").passwordParameter("password").usernameParameter("username")// 认证成功 redirect跳转,根据上一保存请求进行成功跳转.defaultSuccessUrl("/index")// 认证成功 forward跳转,始终在认证成功之后跳转到指定请求
//                .successForwardUrl("/index")
//                .failureForwardUrl("/")/* .successHandler((request, response, exception)->{response.sendRedirect("/index");})*/.failureHandler((request, response, exception) -> {request.setAttribute("msg",exception.getMessage());request.getRequestDispatcher("/").forward(request,response);}).and().logout().logoutUrl("/logout").logoutSuccessUrl("/").and().csrf().disable();return http.build();}
}

这里需要注意的是formLogin认证失败后将不在使用failureForwardUrl()方法转发,而是使用failureHandler处理器方式处理错误信息并跳转页面。

  • 如果使用failureForwardUrl()方式,请到ForwardAuthenticationFailureHandler源码中查看错误信息封装:

SpringSecurity将认证错误信息保存到Request作用域中,并取名为SPRING_SECURITY_LAST_EXCEPTION,所以直接可以到前端页面使用${SPRING_SECURITY_LAST_EXCEPTION}方式进行获取展示。

  • 如果使用failureHandler处理器方式,则可以自定义错误页面及错误信息:

.failureHandler((request, response, exception) -> {//将认证错误信息保存到request作用域,取名为msgrequest.setAttribute("msg",exception.getMessage());//认证失败后转发到指定页面request.getRequestDispatcher("/").forward(request,response);
})

本次案例使用的是自定义failureHandler处理器方式,修改登录页面login.ftl加入错误信息展示区域:

<div>${msg!}</div>

2.5.启动测试

在sys_user表中添加测试用户信息,此处请使用明文密码方式进行身份验证。

修改IndexController中的跳转到首页的方法,加入获取SpringSecurity认证信息并带入前段页面进行展示。

@RequestMapping("/index")
public String toIndex(Model model){//获取Spring Security认证成功后的相关信息Authentication authentication = SecurityContextHolder.getContext().getAuthentication();//将认证信息转换成JSON数据String json = JSON.toJSONString(authentication);//存入数据模型中带入前端页面进行展示model.addAttribute("auth",json);return "index";
}

启动项目并进行登录测试。

index.ftl首页中通过${auth}展示SpringSecurity认证成功的相关信息。

3.密码方式

Spring Security提供了多种密码加密方式,大致可以归类于以下几种:

  • 对密码进行明文处理,即不采用任何加密方式;

  • 采用MD5加密方式;

  • 采用哈希算法加密方式;

3.1.自定义MD5加密

创建自定义MD5加密类并实现PasswordEncoder

public class CustomMd5PasswordEncoder implements PasswordEncoder {@Overridepublic String encode(CharSequence rawPassword) {//对密码进行 md5 加密String md5Password = DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes());System.out.println(md5Password);return md5Password;}
​@Overridepublic boolean matches(CharSequence rawPassword, String encodedPassword) {// 通过md5校验System.out.println(rawPassword);System.out.println(encodedPassword);return encode(rawPassword).equals(encodedPassword);}
}
修改SecurityConfig配置类,更换密码编码器:@Bean
public PasswordEncoder passwordEncoder(){// 自定义MD5加密方式:return new CustomMd5PasswordEncoder();
}

数据库中的用户密码也需要更换成对应自定义MD5加密密码:

//MD5自定义加密方式:
String pwd =  DigestUtils.md5DigestAsHex("123456".getBytes());
System.out.println(pwd);

最后,将生成的MD5加密密码保存到数据库表中。

3.2.BCryptPasswordEncoder密码编码器

BCryptPasswordEncoderSpring Security中一种基于bcrypt算法的密码加密方式。bcrypt算法是一种密码哈希函数,具有防止彩虹表攻击的优点,因此安全性较高。

使用BCryptPasswordEncoder进行密码加密时,可以指定一个随机生成的salt值,将其与原始密码一起进行哈希计算。salt值可以增加密码的安全性,因为即使两个用户使用相同的密码,由于使用不同的salt值进行哈希计算,得到的哈希值也是不同的。

Spring Security中,可以通过在SecurityConfig配置类中添加以下代码来使用BCryptPasswordEncoder进行密码加密:

@Bean
public PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();
}

这样就可以在Spring Security中使用BCryptPasswordEncoder进行密码加密了。

4.RememberMe

在实际开发中,为了用户登录方便常常会启用记住我(Remember-Me)功能。如果用户登录时勾选了“记住我”选项,那么在一段有效时间内,会默认自动登录,免去再次输入用户名、密码等登录操作。该功能的实现机理是根据用户登录信息生成 Token 并保存在用户浏览器的 Cookie 中,当用户需要再次登录时,自动实现校验并建立登录态的一种机制。

Spring Security提供了两种 Remember-Me 的实现方式:

  • 简单加密 Token:用散列算法加密用户必要的登录系信息并生成 Token 令牌。

  • 持久化 Token:数据库等持久性数据存储机制用的持久化 Token 令牌。

基于持久化Token配置步骤如下:

  • 创建数据库表 persistent_logins,用于存储自动登录信息

CREATE TABLE `persistent_logins` (`username` varchar(64) NOT NULL,`series` varchar(64) PRIMARY KEY,`token` varchar(64) NOT NULL,`last_used` timestamp NOT NULL
);

该步骤可以不做,在后续的配置过程中可以交由SpringSecurity自动生成。

  • 基于持久化Token配置,修改SecurityConfig配置类:

Remember-Me 功能的开启需要在configure(HttpSecurity http)方法中通过http.rememberMe()配置,该配置主要会在过滤器链中添加 RememberMeAuthenticationFilter 过滤器,通过该过滤器实现自动登录。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
​//省略其他配置,参考之前@Autowiredpublic UserDetailsService userDetailsService;@Resourcepublic DataSource dataSource;/*** 配置持久化Token方式,注意tokenRepository.setCreateTableOnStartup()配置*/@Beanpublic PersistentTokenRepository persistentTokenRepository(){JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();tokenRepository.setDataSource(dataSource);// 设置为true要保障数据库该表不存在,不然会报异常哦// 所以第二次打开服务器应用程序的时候得把它设为falsetokenRepository.setCreateTableOnStartup(false);return tokenRepository;}@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
​http.authorizeRequests().antMatchers("/").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/").loginProcessingUrl("/user/userLogin").passwordParameter("password").usernameParameter("username")// 认证成功 redirect跳转,根据上一保存请求进行成功跳转.defaultSuccessUrl("/index")// 认证成功 forward跳转,始终在认证成功之后跳转到指定请求//.successForwardUrl("/index")//failureForwardUrl("/")/*.successHandler((request, response, exception)->{response.sendRedirect("/index");})*/.failureHandler((request, response, exception) -> {request.setAttribute("msg",exception.getMessage());request.getRequestDispatcher("/").forward(request,response);}).and().rememberMe()// 指定 rememberMe 的参数名,用于在表单中携带 rememberMe 的值。//.rememberMeParameter("remember-me")// 指定 rememberMe 的有效期,单位为秒,默认2周。.tokenValiditySeconds(30)// 指定 rememberMe 的 cookie 名称。.rememberMeCookieName("remember-me-cookie")// 指定 rememberMe 的 token 存储方式,可以使用默认的 PersistentTokenRepository 或自定义的实现。.tokenRepository(persistentTokenRepository())// 指定 rememberMe 的认证方式,需要实现 UserDetailsService 接口,并在其中查询用户信息。.userDetailsService(userDetailsService).and().logout().logoutUrl("/logout").logoutSuccessUrl("/").and().csrf().disable();return http.build();}
}

rememberMe主要方法介绍:

方法说明
rememberMeParameter()指定在登录时“记住我”的 HTTP 参数,默认为 remember-me
tokenValiditySeconds()设置 Token 有效期为 200s,默认时长为 2 星期
tokenRepository()指定 rememberMe 的 token 存储方式,可以使用默认的 PersistentTokenRepository 或自定义的实现
userDetailsService()指定 UserDetailsService 对象
rememberMeCookieName()指定 rememberMecookie 名称

  • 修改登录页面login.ftl,添加remember-Me记住我的checkbox选项框。

<form action="/user/userLogin" method="post"><label>账号:</label><input type="text" name="username"/><br/><label>密码:</label><input type="password" name="password"/><br/><input type="checkbox" name="remember-me"/>记住我<br/><input type="submit" value="登 录"/>
</form>

注意:配置的checkbox复选框的name属性名要与上面配置的rememberMeParameter("属性名")一致,默认就叫remember-me

总结:remember-me 只有在 JSESSIONID 失效和SecurityContextPersistenceFilter 过滤器认证失败或者未进行认证时才发挥作用。此时,只要 remember-meCookie 不过期,我们就不需要填写登录表单,就能实现再次登录,并且 remember-me 自动登录成功之后,会生成新的 Token 替换旧的 Token,相应 CookieMax-Age 也会重置。

5.CSRF防御

5.1.什么是CSRF

CSRFCross-Site Request Forgery,跨站请求伪造)是一种利用用户已登录的身份在用户不知情的情况下发送恶意请求的攻击方式。攻击者可以通过构造恶意链接或者伪造表单提交等方式,让用户在不知情的情况下执行某些操作,例如修改密码、转账、发表评论等。

为了防范CSRF攻击,常见的做法是在请求中添加一个CSRF Token(也叫做同步令牌、防伪标志),并在服务器端进行验证。CSRF Token是一个随机生成的字符串,每次请求都会随着请求一起发送到服务器端,服务器端会对这个Token进行验证,如果Token不正确,则拒绝执行请求。

5.2.SpringSecurity中如何使用CSRF

Spring Security中,防范CSRF攻击可以通过启用CSRF保护来实现。启用CSRF保护后,Spring Security会自动在每个表单中添加一个隐藏的CSRF Token字段,并在服务器端进行验证。如果Token验证失败,则会抛出异常,从而拒绝执行请求。启用CSRF保护的方式是在Spring Security配置文件中添加.csrf()方法,例如:

http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());

在上面的配置中,我们使用了CookieCsrfTokenRepository作为CSRF Token的存储方式,并设置了httpOnlyfalse,以便在客户端可以访问到该Token

.csrf()主要方法介绍:

方法说明
disable()关闭CSRF防御
csrfTokenRepository()设置CookieCsrfTokenRepository实例,用于存储和检索CSRF令牌。与HttpSessionCsrfTokenRepository不同,CookieCsrfTokenRepositoryCSRF令牌存储在cookie中,而不是在会话中。
ignoringAntMatchers()设置一组Ant模式,用于忽略某些请求的CSRF保护。例如,如果您想要忽略所有以/api/开头的请求,可以使用.ignoringAntMatchers("/api/**")
csrfTokenManager()设置CsrfTokenManager实例,用于管理CSRF令牌的生成和验证。默认情况下,Spring Security使用DefaultCsrfTokenManager实例来生成和验证CSRF令牌。
requireCsrfProtectionMatcher()设置RequestMatcher实例,用于确定哪些请求需要进行CSRF保护。默认情况下,Spring Security将对所有非GET、HEAD、OPTIONS和TRACE请求进行CSRF保护。

重启项目进行测试。

  • 问题一:开启了SpringSecurityCSRF防御之后导致登录的POST请求失败?

原因分析:使用了 spring-security 后,默认开启了防止跨域攻击的功能,任何 POST 提交到后台的表单都要验证是否带有 _csrf 参数,一旦传来的 _csrf 参数不正确,服务器便返回 403 错误。

解决方案:修改login.ftl页面代码,加入_csrf隐藏域。

<form action="/user/userLogin" method="post"><input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/><label>账号:</label><input type="text" name="username"/><br/><label>密码:</label><input type="password" name="password"/><br/><input type="checkbox" name="remember-me"/>记住我<br/><input type="submit" value="登 录"/>
</form>

如果针对一些特定的请求接口,不需要进行CSRF防御,可以通过以下配置忽略:

http.csrf().ignoringAntMatchers("/upload"); // 禁用/upload接口的CSRF防御

  • 问题二:SpringSecurity退出登录/logout提示404问题

退出登录logout实现方式:

http.logout().logoutUrl("/logout").logoutSuccessUrl("/").permitAll();

结果运行项目,执行安全退出时提示页面404错误。

错误原因:SpringSecurity3.2开始,默认会启动CSRF防护,一旦启动了CSRF防护,“/logout” 需要用post的方式提交,SpringSecurity才能过滤。

  • 方式一:配置文件直接关闭CSRF防护

http.csrf().disable();  //关闭csrf防护

注意:当关闭CSRF防护时,部分的页面可能会无法刷新,甚至报错。这时可以在页面的<header>标签之间加入以下代码:

<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>

  • 方式二:官方建议使用POST请求退出登陆,并携带CRSF令牌

http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/").permitAll();

相关文章:

Springsecurty【2】认证连接MySQL

1.前期准备 基于Spring Initializr创建SpringBoot项目&#xff08;基于SpringBoot 2.7.12版本&#xff09;&#xff0c;实现与MyBatisPlus的项目整合。分别导入&#xff1a;CodeGenerator和MyBatisPlusConfig。 CodeGenerator&#xff1a;用于MybatisPlus代码生成&#xff1b;…...

.Net 访问电子邮箱-LumiSoft.Net,好用

序言&#xff1a; 网上找了很多关于.Net如何访问电子邮箱的方法&#xff0c;但是大多数都达不到想要的需求&#xff0c;只有一些 收发邮件。因此 花了很大功夫去看 LumiSoft.Net.dll 的源码&#xff0c;总算做出自己想要的结果了&#xff0c;果然学习诗人进步。 介绍&#xff…...

谷粒商城-商品服务-新增商品功能开发(商品图片无法展示问题没有解决)

在网关配置路由 - id: member_routeuri: lb://gulimemberpredicates:- Path/api/gulimember/**filters:- RewritePath/api/(?<segment>.*),/$\{segment}并将所有逆向生成的工程调式出来 获取分类关联的品牌 例如&#xff1a;手机&#xff08;分类&#xff09;-> 品…...

Open3D 点云数据处理基础(Python版)

Open3D 点云数据处理基础&#xff08;Python版&#xff09; 文章目录 1 概述 2 安装 2.1 PyCharm 与 Python 安装 2.3 Anaconda 安装 2.4 Open3D 0.13.0 安装 2.5 新建一个 Python 项目 3 点云读写 4 点云可视化 2.1 可视化单个点云 2.2 同一窗口可视化多个点云 2.3…...

使用vue-qr,报错in ./node_modules/vue-qr/dist/vue-qr.js

找到node_modules—>vue-qr/dist/vue-qr.js文件&#xff0c;搜…e,将…去掉&#xff0c;然后重新运行项目。...

百川2大模型微调问题解决

之前用https://github.com/FlagAlpha/Llama2-Chinese微调过几个模型&#xff0c;总体来说llama2的生态还是比较好的&#xff0c;过程很顺利。微调百川2就没那么顺利了&#xff0c;所以简单做个记录 1. 数据准备&#xff0c;我的数据是单轮对话&#xff0c;之前微调llama2已经按…...

MySQL的事务-原子性

MySQL的事务处理具有ACID的特性&#xff0c;即原子性&#xff08;Atomicity)、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;和持久性&#xff08;Durability&#xff09;。 1. 原子性指的是事务中所有操作都是原子性的&#xff0c;要…...

D3839|完全背包

完全背包&#xff1a; 首先01背包的滚动数组中的解法是内嵌的循环是从大到小遍历&#xff0c;为了保证每个物品仅被添加一次。 for(int i 0; i < weight.size(); i) { // 遍历物品for(int j bagWeight; j > weight[i]; j--) { // 遍历背包容量dp[j] max(dp[j], dp[j…...

Java之Synchronized与锁升级

Synchronized与锁升级 一、概述 在多线程并发编程中 synchronized 一直是元老级角色&#xff0c;很多人都会称呼它为重量级锁。但是&#xff0c;随着 Java SE 1.6 对 synchronized 进行了各种优化之后&#xff0c;有些情况下它就并不那么重了。 本文详细介绍 Java SE 1.6 中为…...

kitex出现:open conf/test/conf.yaml: no such file or directory

open conf/test/conf.yaml: no such file or directory https://github.com/cloudwego/cwgo/issues/120 https://github.com/cloudwego/cwgo/issues/29 在使用Kitex生成的代码中&#xff0c;单元测试时回报错&#xff0c;如标题所示。出现该错的原因是&#xff0c;biz/servic…...

sql server多表查询

查询目标 现在有学生表和学生选课信息表&#xff0c;stu和stuSelect&#xff0c;stu中包含学生用户名、名字&#xff0c;stuSelect表中包含学生用户名&#xff0c;所选课程名 学生表&#xff1a; nameusername李明Li Ming李华Li Hua 学生选课表&#xff1a; usernameCourse…...

如何利用PPT绘图并导出清晰图片

在写论文的过程中&#xff0c;免不了需要绘图&#xff0c;但是visio等软件绘图没有在ppt上绘图比较熟练&#xff0c;尤其流程图结构图. 但是ppt导出的图片也不够清晰&#xff0c;默认分辨率是96dpi&#xff0c;而杂志投稿一般要求至300dpi。解决办法如下&#xff1a; 1.打开注…...

1.倒排索引 2.逻辑斯提回归算法

1.倒排索引 https://help.aliyun.com/zh/open-search/retrieval-engine-edition/introduction-to-inverted-indexes 倒排索引&#xff08;Inverted Index&#xff09;是一种数据结构&#xff0c;用于快速查找包含某个特定词或词语的文档。它主要用于全文搜索引擎等应用&#…...

Kafka消费者组

消费者总体工作流程 Consumer Group&#xff08;CG&#xff09;&#xff1a;消费者组&#xff0c;由多个consumer组成。形成一个消费者组的条件&#xff0c;是所有消费者的groupid相同。 • 消费者组内每个消费者负责消费不同分区的数据&#xff0c;一个分区只能由一个组内消费…...

四. 基于环视Camera的BEV感知算法-BEVDepth

目录 前言0. 简述1. 算法动机&开创性思路2. 主体结构3. 损失函数4. 性能对比总结下载链接参考 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第四章——基于环视Cam…...

CentOS系统环境搭建(二十五)——使用docker compose安装mysql

centos系统环境搭建专栏&#x1f517;点击跳转 文章目录 使用docker compose安装mysqlMySQL81.新建文件夹2.创建docker-compose.yaml3.创建my.cnf4.mysql容器的启动和关闭 MySQL5.71.新建文件夹2.创建docker-compose.yaml3.创建my.cnf4.mysql容器的启动和关闭 使用docker comp…...

协作机器人(Collaborative-Robot)安全碰撞的速度与接触力

协作机器人&#xff08;Collaborative-Robot&#xff09;的安全碰撞速度和接触力是一个非常重要的安全指标。在设计和使用协作机器人时&#xff0c;必须确保其与人类或其他物体的碰撞不会对人员造成伤害。 对于协作机器人的安全碰撞速度&#xff0c;一般会设定一个上限值&…...

第11章 GUI Page400~402 步骤二 画直线

运行效果&#xff1a; 源代码&#xff1a; /**************************************************************** Name: wxMyPainterApp.h* Purpose: Defines Application Class* Author: yanzhenxi (3065598272qq.com)* Created: 2023-12-21* Copyright: yanzhen…...

华为gre隧道全部跑静态路由

最终实现&#xff1a; 1、pc1能用nat上网ping能pc3 2、pc1能通过gre访问pc2 3、全部用静态路由做&#xff0c;没有用ospf&#xff0c;如果要用ospf&#xff0c;那么两边除了路由器上跑ospf&#xff0c;核心交换机也得用ospf r2配置&#xff1a; acl number 3000 rule 5 deny…...

【c++】入门1

c关键字 命名空间 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c;以避免命名冲突或名字污染&#xff…...

Python之Django项目的功能配置

1.创建Django项目 进入项目管理目录&#xff0c;比如&#xff1a;D盘 执行命令&#xff1a;diango-admin startproject demo1 创建项目 如果提示diango命令不存在&#xff0c;搜索diango-admin程序的位置&#xff0c;然后加入到环境变量path中。 进入项目&#xff0c;cd demo…...

P4 音频知识点——PCM音频原始数据

目录 前言 01 PCM音频原始数据 1.1 频率 1.2 振幅&#xff1a; 1.3 比特率 1.4 采样 1.5 量化 1.6 编码 02. PCM数据有以下重要的参数&#xff1a; 采样率&#xff1a; 采集深度 通道数 ​​​​​​​ PCM比特率 ​​​​​​​ PCM文件大小计算&#xff1a; ​…...

解决Electron中WebView加载部分HTTPS页面白屏的方法

Electron是一个开源的桌面应用程序框架&#xff0c;它允许使用Web技术构建跨平台的桌面应用。在Electron应用中&#xff0c;WebView 是一个常用的组件&#xff0c;用于嵌套加载Web内容。然而&#xff0c;有时候在加载使用 HTTPS 协议的页面时&#xff0c;可能会因为证书问题导致…...

【Java中创建对象的方式有哪些?】

✅Java中创建对象的方式有哪些&#xff1f; ✅使用New关键字✅使用反射机制✅使用clone方法✅使用反序列化✅使用方法句柄✅ 使用Unsafe分配内存 ✅使用New关键字 这是我们最常见的也是最简单的创建对象的方式&#xff0c;通过这种方式我们还可以调用任意的构造函数 (无参的和有…...

npm使用详解(好吧好吧是粗解)

目录 npm是什么&#xff1f; npm有什么用&#xff1f; npm安装 在 Windows 上 在 macOS 上 在 Linux 上&#xff08;使用 apt 包管理器为例&#xff09; 验证 npm 安装成功&#xff1a; npm使用 1. 初始化项目&#xff1a; 2. 安装和管理依赖&#xff1a; 3. 查看和…...

uniapp自定义头部导航怎么实现?

一、在pages.json文件里边写上自定义属性 "navigationStyle": "custom" 二、在对应的index页面写上以下&#xff1a; <view :style"{ height: headheight px, backgroundColor: #24B7FF, zIndex: 99, position: fixed, top: 0px, width: 100% …...

什么是 Dubbo?它有哪些核心功能?

文章目录 什么是 Dubbo&#xff1f;它有哪些核心功能&#xff1f; 什么是 Dubbo&#xff1f;它有哪些核心功能&#xff1f; Dubbo 是一款高性能、轻量级的开源 RPC 框架。由 10 层模式构成&#xff0c;整个分层依赖由上至下。 通过这张图我们也可以将 Dubbo 理解为三层模式&…...

(2021|CoRR,AugCLIP,优化)FuseDream:通过改进的 CLIP+GAN 空间优化实现免训练文本到图像生成

FuseDream: Training-Free Text-to-Image Generation with Improved CLIPGAN Space Optimization 公众&#xff1a;EDPJ&#xff08;添加 VX&#xff1a;CV_EDPJ 或直接进 Q 交流群&#xff1a;922230617 获取资料&#xff09; 目录 0. 摘要 1. 简介 2. CLIPGAN 文本到图…...

python pip安装依赖的常用软件源

目录 引言 一、什么是镜像源&#xff1f;​​​​​​​ 二、清华源 三、阿里源 四、中科大源 五、豆瓣源 六、更多资源 引言 在软件开发和使用过程中&#xff0c;我们经常需要下载和更新各种软件包和库文件。然而&#xff0c;由于网络环境的限制或者服务器的负载&#…...

避免大M取值过大引起的数值问题

在数学建模当中&#xff0c;常常会见到大M法&#xff0c;它之所以叫大M法&#xff0c;是因为它涉及到一个&#xff08;绝对值&#xff09;较大的系数M&#xff0c;这个大M的值应大于约束中的连续变量或者约束表达式可能取到的任何合理值&#xff0c;M值取过大往往会造成优化问题…...

史密斯圆图的使用

史密斯圆图的使用 简介识别史密斯圆图等反射系数圆归一化阻抗圆导纳圆图史密斯圆图的使用单支匹配双支匹配简介 史密斯图Smith Chart是电气工程,无线电,射频工程,微波工程和通信等领域常用的一种图示工具,用于分析和设计传输线和阻抗匹配网络,它由美国工程师Phillip H.Sm…...

可重复读解决了哪些问题? 对 SQL 慢查询会考虑哪些优化 ?

文章目录 可重复读解决了哪些问题&#xff1f;对 SQL 慢查询会考虑哪些优化 &#xff1f; 可重复读解决了哪些问题&#xff1f; &#xff08;1&#xff09;可重复读的核心就是一致性读(consistent read);保证多次读取同一个数据时&#xff0c;其值都和事务开始时候的内容是一致…...

从0开始python学习-35.allure报告企业定制

目录 1. 搭建allure环境 2. 生成报告 3. logo定制 4. 企业级报告内容或层级定制 5. allure局域网查看 1. 搭建allure环境 1.1 JDK&#xff0c;使用PyCharm 找到pycharm安装目录找到java.exe记下jbr目录的完整路径&#xff0c;eg: C:\Program Files\JetBrains\PyCharm Com…...

蓝桥杯2020年10月青少组Python程序设计省赛真题

1、设计一个猜字母的程序,程序随机给出26个小写字母中的一个,答题者输入猜测的字母,若输入的不是26个小写字母之一,让用户重新输入,若字母在答案之前或之后,程序给出相应正确提示,如答错5次,则答题失败并退出游戏,若回答正确,程序输出回答次数并退出游戏。 2、试编一个“口…...

【数据结构】布隆过滤器原理详解及其代码实现

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…...

Qt中实现短信验证码功能

在Qt中实现短信验证码功能,可以使用Qt的信号槽机制和计时器来实现。 首先,在mainwindow.h头文件中添加下列代码: #include <QMainWindow> #include <QTimer>namespace Ui {class MainWindow; }class MainWindow : public...

Redis-运维

转自 极客时间 Redis 亚风 原文视频&#xff1a;https://u.geekbang.org/lesson/535?article681062 Redis 同步 Redis主从数据同步,主从第⼀次同步是全量同步 replicaof 主机 端口 #当前这个机器做Master的备份master如何判断slave是不是第⼀次来同步数据&#xff1a; Repl…...

Qt制作定时关机小程序

文章目录 完成效果图ui界面ui样图 main函数窗口文件头文件cpp文件 引言 一般定时关机采用命令行模式&#xff0c;还需要我们计算在多久后关机&#xff0c;我们可以做一个小程序来定时关机 完成效果图 ui界面 <?xml version"1.0" encoding"UTF-8"?>…...

LeetCode day30

LeetCode day30 害&#xff0c;昨天和今天在搞数据结构的报告&#xff0c;后面应该也会把哈夫曼的大作业写上来。 今天认识认识贪心算法。(&#xff61;&#xff65;∀&#xff65;)&#xff89; 2697. 字典序最小回文串 给你一个由 小写英文字母 组成的字符串 s &#xff0c;…...

数据分析基础之《numpy(5)—合并与分割》

了解即可&#xff0c;用panads 一、作用 实现数据的切分和合并&#xff0c;将数据进行切分合并处理 二、合并 1、numpy.hstack 水平拼接 # hstack 水平拼接 a np.array((1,2,3)) b np.array((2,3,4)) np.hstack((a, b))a np.array([[1], [2], [3]]) b np.array([[2], […...

centos 安装 Miniconda

在 CentOS 上安装 Miniconda 的步骤通常包括下载 Miniconda 安装脚本、运行脚本以及配置环境。以下是详细步骤&#xff1a; 1. 下载 Miniconda 安装脚本 首先&#xff0c;您需要从 Miniconda 的官方网站下载适用于 Linux 的安装脚本。您可以使用 wget 命令在 CentOS 终端中直…...

第二百二十六回

文章目录 1. 概念介绍2. 具体细节2.1 发现服务2.2 发现特征值2.3 发送数据2.4 接收数据 3. 代码与效果3.13.2 运行效果 4. 经验总结 我们在上一章回中介绍了"连接蓝牙设备的细节"相关的内容&#xff0c;本章回中将介绍通过蓝牙发送数据的细节.闲话休提&#xff0c;让…...

ubuntu常用指令

Ubuntu是一个基于Linux的操作系统&#xff0c;它使用了大量的命令行指令。这些指令对于管理系统、处理文件、监控资源和执行各种任务都非常有用。以下是一些常用的Ubuntu命令&#xff1a; 系统管理 sudo&#xff1a;提供管理员权限执行命令&#xff08;例如 sudo apt update&a…...

Quartz.NET 事件监听器

1、调度器监听器 调度器本身收到的一些事件通知&#xff0c;接口ISchedulerListener&#xff0c;如作业的添加、删除、停止、挂起等事件通知&#xff0c;调度器的启动、关闭、出错等事件通知&#xff0c;触发器的暂停、挂起等事件通知&#xff0c;接口部分定义如下&#xff1a…...

2024-AI人工智能学习-安装了pip install pydot但是还是报错

2024-AI人工智能学习-安装了pip install pydot但是还是报错 出现这样子的错误&#xff1a; /usr/local/bin/python3.11 /Users/wangyang/PycharmProjects/studyPython/tf_model.py 2023-12-24 22:59:02.238366: I tensorflow/core/platform/cpu_feature_guard.cc:182] This …...

在使用mapstruct,想忽略掉List<DTO>字段里面的,`data` 字段的映射, 如何写ignore: 使用@IterableMapping

在使用mapstruct,想忽略掉List字段里面的,data 字段的映射, 如何写ignore 代码如下: public interface AssigmentFileMapper {AssigmentFileDTO assigmentFileToAssigmentFileDTO(AssigmentFile assigmentFile);AssigmentFile assigmentFileDTOToAssigmentFile(Assigment…...

ansible-playbook的Temlates模块 tags模块 Roles模块

Temlates模块 jinja模板架构&#xff0c;通过模板可以实现向模板文件传参(python转义)把占位符参数传到配置文件中去,生产一个目标文本文件&#xff0c;传递变量到需要的配置文件当中 &#xff08;web开发&#xff09; nginx.conf.j2 早文件当中配置的是占位符&#xff08;声明…...

Canal使用详解

Canal介绍 Canal是阿里巴巴开发的MySQL binlog增量订阅&消费组件&#xff0c;Canal是基于MySQL二进制日志的高性能数据同步系统。在阿里巴巴集团中被广泛使用&#xff0c;以提供可靠的低延迟增量数据管道。Canal Server能够解析MySQL Binlog并订阅数据更改&#xff0c;而C…...

【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…...

C#和.Net常见问题记录

什么是.NET框架&#xff0c;.NET框架与C#(C Sharp)是什么关系&#xff1f; .NET框架是由Microsoft设计和维护的软件开发框架&#xff0c;.NET框架提供了C#(编程语言)开发的所有基础设施和支持。通过使用C#和.NET框架&#xff0c;开发者可以轻松地开发高质量、高效率的应…...