基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【二】【整合springSecurity】
1、创建数据库
注意:mysql默认字符集为utf8,默认排序规则为utf8_general_ci。一般我们也会选择字符集为utf-8
MySQL在5.5.3之后增加了这个utf8mb4的编码,utf8mb4完全向下兼容utf8,为了节省空间,一般情况下使用utf8也就够了,我这边没有utf8。所以选择了utf8mb4 。

2、建表
若需要整合我们的springSecurity,一种是直接使用springSecurity自带的权限架构,另外一种是使用我们自己设计的数据架构,本文所阐述的就是使用自己设计的RBAC权限架构,因此我们要事先设计好用户权限架构的PDM如下图所示,并创建我们的数据库:数据库名:hyll_springboot,以及我们的三张表:user、user_role、user_associate_role:



接着打开我们的工程新建如下工程的目录:

接着在我们的sys包底下新建entity和dao这两个包:

同时打开我们的pom.xml引入该工程所需要的所有依赖,接着我们的IDEA会弹出一个框,我们点击import就自动会去maven给我们下载依赖,若你有自己的私有maven则将其指向自己的私有maven,若这边有缺少不懂的直接去我的第一章的github上的源代码中自己去copy下来:
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><mysql.version>5.1.41</mysql.version><guava.version>18.0</guava.version><org.mapstruct.version>1.1.0.Final</org.mapstruct.version></properties><dependencies><!-- 集成Druid数据库连接池和监控 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.3</version></dependency><!-- 引入mybatis的支持 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.1</version></dependency><!-- 引入mapstruct的支持 --><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct-jdk8</artifactId><version>${org.mapstruct.version}</version></dependency><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${org.mapstruct.version}</version></dependency><!-- Java EE 6 规范 JSR 330 --><dependency><groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><version>1</version></dependency><!-- 引入json的依赖 classifier必须要加这个是json的jdk的依赖--><dependency><groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId><version>2.4</version><classifier>jdk15</classifier></dependency><!-- 开启spring-websocket的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><!-- 开启spring-security的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- 开启thymeleaf的spring-security的支持 --><dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity4</artifactId></dependency><!-- 表示对thymeleaf模板不再是用默认的HTML5标准来做严格限制 --><dependency><groupId>net.sourceforge.nekohtml</groupId><artifactId>nekohtml</artifactId><version>1.9.22</version></dependency><!-- 添加对spring-redis的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-redis</artifactId><version>1.3.8.RELEASE</version></dependency><!-- 添加对spring-cache的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId></dependency><!-- 添加对spring-data-rest的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-rest</artifactId></dependency><!-- 添加对spring-jpa的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>${guava.version}</version></dependency><!-- 添加对thymeleaf的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- 添加对websocket的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><version>1.3.5.RELEASE</version><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional><!-- optional=true,依赖不会传递,该项目依赖devtools;之后依赖myboot项目的项目如果想要使用devtools,需要重新引入 --></dependency><dependency><groupId>com.xiaoleilu</groupId><artifactId>hutool-all</artifactId><version>3.0.9</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.6.1</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.6.1</version></dependency><dependency><groupId>com.vaadin.external.google</groupId><artifactId>android-json</artifactId><version>0.0.20131108.vaadin1</version></dependency></dependencies>
同时在我们的entity包底下新建我们刚刚的三个实体:

UserRole 的代码部分
package com.example.demo.sys.entity;/*** @author lj* @version 1.0* @date 2023/1/314:18* Description:com.example.demo.sys.entity*/
public class UserRole {private long id;private String name;private String roleName;public long getId() {return id;}public void setId(long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getRoleName() {return roleName;}public void setRoleName(String roleName) {this.roleName = roleName;}
}
User 代码部分
package com.example.demo.sys.entity;import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;/*** @author lj* @version 1.0* @date 2023/1/310:01* Description:com.example.demo.sys.entity*/
public class User implements UserDetails {private int id;private String login;private String password;private String userName;private String address;private String job;private long groupId;private Date birthDate;private String city;private String district;private String province;private String streetAddress;private String state;private String type;private Date lastLoginDate;// 用户角色信息private List<UserRole> roles;// 权限集合数据private String roleArray;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getLogin() {return login;}public void setLogin(String login) {this.login = login;}public void setPassword(String password) {this.password = password;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public String getJob() {return job;}public void setJob(String job) {this.job = job;}public long getGroupId() {return groupId;}public void setGroupId(long groupId) {this.groupId = groupId;}public Date getBirthDate() {return birthDate;}public void setBirthDate(Date birthDate) {this.birthDate = birthDate;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public String getDistrict() {return district;}public void setDistrict(String district) {this.district = district;}public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getStreetAddress() {return streetAddress;}public void setStreetAddress(String streetAddress) {this.streetAddress = streetAddress;}public String getState() {return state;}public void setState(String state) {this.state = state;}public String getType() {return type;}public void setType(String type) {this.type = type;}public Date getLastLoginDate() {return lastLoginDate;}public void setLastLoginDate(Date lastLoginDate) {this.lastLoginDate = lastLoginDate;}public List<UserRole> getRoles() {return roles;}public void setRoles(List<UserRole> roles) {this.roles = roles;}public String getRoleArray() {return roleArray;}public void setRoleArray(String roleArray) {this.roleArray = roleArray;}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();if (this.getRoles() != null) {List<UserRole> roles = this.getRoles();for (UserRole role : roles) {if (role.getName() != null) {auths.add(new SimpleGrantedAuthority(role.getName()));}}}return auths;}@Overridepublic String getPassword() {return null;}@Overridepublic String getUsername() {return null;}@Overridepublic boolean isAccountNonExpired() {return false;}@Overridepublic boolean isAccountNonLocked() {return false;}@Overridepublic boolean isCredentialsNonExpired() {return false;}@Overridepublic boolean isEnabled() {return false;}/*** 功能描述:组装角色数据集合** @param roleArray*/public void packagingRoles(String roleArray) {List<UserRole> roles = new ArrayList<UserRole>();if (roleArray != null) {UserRole userRole = null;for (String roleId : roleArray.split(",")) {if (!roleId.isEmpty()) {userRole = new UserRole();userRole.setId(Long.parseLong(roleId));roles.add(userRole);}}}this.setRoles(roles);}}
UserAssociateRole 代码部分
package com.example.demo.sys.entity;/*** @author lj* @version 1.0* @date 2023/1/314:26* Description:com.example.demo.sys.entity*/
public class UserAssociateRole {private int userId;private long roleId;public UserAssociateRole() {super();}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}public long getRoleId() {return roleId;}public void setRoleId(long roleId) {this.roleId = roleId;}
}
接着我们在dao包里面创建以下的接口:
package com.example.demo.sys.dao;import com.example.demo.sys.entity.User;/*** @author lj* @version 1.0* @date 2023/1/314:54* Description:com.example.demo.sys.dao*/
public interface UserDao {/*** 功能描述:根据账户获取用户信息** @param user* @return com.example.demo.sys.entity.User* @author: LJ* @date: 2023/1/3*/User findByLogin(String user);
}
接着我们引入我们的mybatis配置以及我们的security和快速切换环境配置,
首先在我们的application.properties底下增加以下配置:
spring.profiles.active=dev#配置放行的目录和方法
security.ignored=/api/*,/css/*,/js/*,/images/*,/fonts/*,/font-awesome/*
#表示对thymeleaf模板不再是用默认的HTML5标准来做严格限制
spring.thymeleaf.mode = LEGACYHTML5#配置mybatis的扫描的包的文件的入口
mybatis.config-locations=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
同时在我们的resources目录底下创建一个目录mybatis并在该目录底下创建一个文件mybatis-config.xml和mapper目录如下所示:

mybatis-config.xml代码如下所示
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><typeAlias alias="Integer" type="java.lang.Integer" /><typeAlias alias="Long" type="java.lang.Long" /><typeAlias alias="HashMap" type="java.util.HashMap" /><typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" /><typeAlias alias="ArrayList" type="java.util.ArrayList" /><typeAlias alias="LinkedList" type="java.util.LinkedList" /></typeAliases>
</configuration>
同时在我们的resource目录底下创建我们的application-dev.properties文件信息如下:
server.port = 8080
#数据库连接配置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/hyll_springboot?characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=111111
接着我们在resource/mapper目录底下创建一个mybatis_user.xml内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><typeAlias alias="Integer" type="java.lang.Integer" /><typeAlias alias="Long" type="java.lang.Long" /><typeAlias alias="HashMap" type="java.util.HashMap" /><typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" /><typeAlias alias="ArrayList" type="java.util.ArrayList" /><typeAlias alias="LinkedList" type="java.util.LinkedList" /></typeAliases>
</configuration>
同时在我们的resource目录底下创建我们的application-dev.properties文件信息如下
server.port = 8080
#数据库连接配置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/hyll_springboot?characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=111111
接着我们在resource/mapper目录底下创建一个mybatis_user.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.sys.dao.UserDao"><!-- 包含角色信息的map --><resultMap type="com.example.demo.sys.entity.User" id="UserLoginMap"><id property="id" column="id"/><result property="login" column="login"/><result property="password" column="password"/><result property="userName" column="user_name"/><result property="address" column="address"/><result property="job" column="job"/><result property="groupId" column="group_id"/><result property="birthDate" column="birth_date"/><result property="city" column="city"/><result property="district" column="district"/><result property="province" column="province"/><result property="streetAddress" column="street_address"/><result property="state" column="state"/><result property="type" column="type"/><result property="lastLoginDate" column="last_login_date"/><collection property="roles" ofType="com.example.demo.sys.entity.UserRole" javaType="java.util.ArrayList"><result column="user_role_id" property="id" jdbcType="VARCHAR" /><result column="name" property="name" jdbcType="VARCHAR" /><result column="role_name" property="roleName" jdbcType="VARCHAR" /></collection></resultMap><!-- 根据账号来获取用户信息 --><select id="findByLogin" parameterType="java.lang.String" resultMap="UserLoginMap">select u.*,ur.id as user_role_id,ur.name,ur.role_name from user u inner join user_associate_role uar on u.id = uar.user_id inner join user_role ur on uar.role_id = ur.id where u.login = #{login}</select></mapper>
接着开始我们的springsecurity的配置,找到我们的config包在该包底下我们创建一个security和mybatis包如下所示

接着在我们的security增加以下三个类分别是(CustomPasswordEncoder:密码加密类;CustomUserService:登陆逻辑重写类;WebSecurityConfig:security实现配置类):
注意maven的版本,如果版本高的话,就没有Md5PasswordEncoder的依赖
package com.example.demo.common.config.security;import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;/*** 功能描述:spring-security登陆的密码进行MD5加密传到数据库** @author: LJ* @date: 2023/1/3* @return*/public class CustomPasswordEncoder implements PasswordEncoder {@Overridepublic String encode(CharSequence rawPassword) {Md5PasswordEncoder encoder = new Md5PasswordEncoder();return encoder.encodePassword(rawPassword.toString(), "hyll");}@Overridepublic boolean matches(CharSequence rawPassword, String encodedPassword) {Md5PasswordEncoder encoder = new Md5PasswordEncoder();return encoder.isPasswordValid(encodedPassword, rawPassword.toString(), "hyll");}
}
注意,你得密码是经过md5加密得,所以比如我得密码是1,那么加密后得a2098ac42fe033111a1f678b8d621899,这个填入到数据库中对应user表得密码中,你可以根据自己的密码进行加密,加密后的结果放到数据库中
public static void main(String[] args) {Md5PasswordEncoder encoder = new Md5PasswordEncoder();System.out.println(encoder.encodePassword("1", "hyll"));System.out.println( encoder.isPasswordValid("a2098ac42fe033111a1f678b8d621899","1", "hyll"));}

package com.example.demo.common.config.security;import com.example.demo.sys.dao.UserDao;
import com.example.demo.sys.entity.User;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;import javax.annotation.Resource;/*** @author lj* @version 1.0* @date 2023/1/510:51* Description:com.example.demo.common.config.security*/
public class CustomUserService implements UserDetailsService {@Resourceprivate UserDao userDao;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {User user = userDao.findByLogin(s);if (user == null) {throw new UsernameNotFoundException("用户名不存在");}
// 自定义错误的文章说明的地址:http://blog.csdn.net/z69183787/article/details/21190639?locationNum=1&fps=1if (user.getState().equalsIgnoreCase("0")) {throw new LockedException("用户账号被冻结,无法登陆请联系管理员!");}return user;}
}
package com.example.demo.common.config.security;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;/*** @author lj* @version 1.0* @date 2023/1/513:34* 实现Security的配置*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
//当我们想要开启spring方法级安全时,只需要在任何 @Configuration实例上使用 @EnableGlobalMethodSecurity 注解就能达到此目的
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@BeanUserDetailsService customUserService() {return new CustomUserService();}@BeanPasswordEncoder passwordEncoder() {return new CustomPasswordEncoder();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(customUserService()).passwordEncoder(passwordEncoder());}@Overrideprotected AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();}/*** 功能描述: csrf().disable()为了关闭跨域访问的限制,若不关闭则websocket无法与后台进行连接** @param http* @return void* @author: LJ* @date: 2023/1/5*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.headers().frameOptions().disable();http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/login").defaultSuccessUrl("/main").failureUrl("/login?error=true").permitAll().and().logout().logoutSuccessUrl("/login").permitAll();}
}
接着我们在mybatis包底下新增MyBatisConfig 配置类如下所示 MapperScan扫描的是我们的dao接口的存放路径,因此此处大家一定要注意自己的dao包的路径是否正确,否则会导致调用dao方法出错】:
package com.example.demo.common.config.mybatis;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;/*** @author lj* @version 1.0* @date 2023/1/2520:15* Description:com.example.demo.common.config.mybatis*/
@Configuration
@MapperScan("com.example.demo.*.dao")
public class MyBatisConfig {
}
接着在我们的config目录底下创建我们的WebMvcConfig配置文件如下所示:
package com.example.demo.common.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;/*** @author lj* @version 1.0* @date 2023/1/2520:21* Description:com.example.demo.common.config*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {/*** 重写方法描述:实现在url中输入相应的地址的时候直接跳转到某个地址** @param registry*/@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/login").setViewName("login");registry.addViewController("/main").setViewName("main");registry.addViewController("/error").setViewName("error");}}
相关文章:
基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【二】【整合springSecurity】
1、创建数据库 注意:mysql默认字符集为utf8,默认排序规则为utf8_general_ci。一般我们也会选择字符集为utf-8 MySQL在5.5.3之后增加了这个utf8mb4的编码,utf8mb4完全向下兼容utf8,为了节省空间,一般情况下使用utf8也就…...
字节6面,成功唬住面试官拿了27K,软件测试面试也没有传说中那么难吧....
字节的面试挺独特,每轮面试都没有 HR 约时间,一般是晚上 8 点左右面试官来一个电话,问是否能面试,能的话开始面,不能就约一个其它时间。全程 6 面,前五面技术面,电话面试,最后一面是…...
Qt扫盲-QMake 语言概述
QMake 语言概述一、概述二、变量三、替换函数四、测试函数一、概述 这里主要就是记录一下如何使用 qmake Manual,里面关于我对 qmake的理解,以及如何配置这个 qt 工程文件,通过配置工程文件,来构建出,APP,…...
代码随想录二刷Day02链表:203.移除链表元素,707.设计链表,206.反转链表
203.移除链表元素(写if的时候,要考虑要不要写else语句) 文章链接:代码随想录 (programmercarl.com) 思路: (1)要操作链表的话,可以设置一个虚拟头节点,从而方便操作 …...
Zabbix 3.0 从入门到精通(zabbix使用详解)
Zabbix 3.0 从入门到精通(zabbix使用详解) 第1章 zabbix监控 1.1 为什么要监控 在需要的时刻,提前提醒我们服务器出问题了 当出问题之后,可以找到问题的根源 网站/服务器 的可用性 1.1.1 网站可用性 在软件系统的高可靠性(也称为可用性…...
基于JDBC框架的事务管理
事务: Transaction, 是数据库中的一种能够保证多个写操作要么全部成功, 要么全部失败的机制在基于Spring JDBC的数据库编程中, 在业务方法上添加Transactional注解, 即可使得这个业务方法是事务性的举例, 一个银行转账操作, 转账时需要执行的sql语句大致是:UPDATE 存款表 SET 余…...
使用IPV6+DDNS连接内网主机
0、前言 IPV6已经普及多年,但是作为互联网用户好像并没有在实用性上有更多感受,或者说IPV6并没有让普通用户感觉到改变。我作为网络从业者其实也没有过多关注。在工作中普遍遇到的还是基于IPV4的网络,比如各个行业的网络、单位的内网区域和互…...
【新2023】华为OD机试 - 高效的任务规划(Python)
华为 OD 清单查看地址:blog.csdn.net/hihell/category_12199275.html 高效的任务规划 题目 你有 n 台机器编号为1-n,每台都需要完成一项工作, 机器经过配置后都能独立完成一项工作。 假设第i台机器你需要花 Bi 分钟进行设置, 然后开始运行,Ji分钟后完成任务。 现在,你…...
sql复习(数据处理、约束)
一、DML(数据操纵语言) DML(Data Manipulation Language – 数据操纵语言) 可以在下列条件下执行: –向表中插入数据 –修改现存数据 –删除现存数据 事务是由完成若干项工作的DML语句组成的 1.insert语句 使用 INSERT 语句向表中插入数据…...
前端入门~
我们应该怎样理解前端呢?前端即网站前台部分,运行在PC端,移动端等浏览器上展现给用户浏览的网页。随着互联网技术的发展,HTML5,CSS3,前端框架的应用,跨平台响应式网页设计能够适应各种屏幕分辨率…...
工业网关控制器CK-GW06-E01与欧姆龙 PLC配置说明
工业网关控制器CK-GW06-E01是一款工业级网关控制器,以太网通信接口,支持 EtherNet IP|Modbus TCP 工业协议。可实现一拖六,同时带有六组输入 检测 IO 和六组输出控制 IO。 本文将重点介绍工业网关控制器CK-GW06-E01与欧姆龙 PLC配置说明。 工…...
uni-app前端H5页面底部内容被tabbar遮挡
如果你想在原生 tabbar 上方悬浮一个菜单,之前写 bottom:0。这样的写法编译到 h5 后,这个菜单会和 tabbar 重叠,位于屏幕底部。 原码: <view style"position: fixed;bottom:0;left: 0;background-color: #007AFF;right: …...
昇腾CANN算子开发揭秘
开发者在利用昇腾硬件进行神经网络模型训练或者推理的过程中,可能会遇到以下场景:1、训练场景下,将第三方框架(例如TensorFlow、PyTorch等)的网络训练脚本迁移到昇腾AI处理器时遇到了不支持的算子。2、推理场景下&…...
华为OD机试注意事项,备考思路,刷题要点,答疑,od Base 提供
华为 OD 机试是华为公司用于招聘岗位的一种在线编程测试,通常要求应聘者在规定的时间内完成一定数量的编程题目,以测试其编程能力和解决问题的能力。 本篇博客就华为 OD 机试注意事项,备考思路,刷题要点,答疑为大家一一…...
Python 自己简单地造一个轮子.whl文件
造轮子引言准备文件原始文件打包轮子文件运行验证引言 平时使用的python第三方库很顺手,这第三方库一般都是大家一起努力的结果,那我们是不是也可以贡献一点力量呢?首先从造一个本地的.whl文件开始。 在python中,引用第三方库时…...
NVIDIA Tesla V100部署与使用
在先前的实验过程中,使用了腾讯云提供的nvidia T4GPU,尽管其性能较博主的笔记本有了极大提升,但总感觉仍有些美中不足,因此本次博主租赁了nvidia V100 GPU,看看它的性能表现如何。 和先前一样,只需要将服务…...
网络知识点梳理与总结
作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页 目录 前言 一.知识点梳理 前言 本章将会对高级网络应用一些知识点进行梳理。 一.知识点梳理 1.单臂的缺陷有哪些?...
我工作5年测试才8K,应届生刚毕业就拿16K?凭什么
我从事手工测试五年了,还拿着8K的死工资,家里还几张嘴需要喂养,我很累,也很迷茫…【某个粉丝跟我的诉说】 为什么手工测试会迷茫呢? 自动化测试、性能测试倒是不会迷茫。 我认为手工测试的迷茫基于两个原因…...
【QT】UDP通信QUdpSocket(单播、广播、组播)
目录1. UDP通信概述2. UDP消息传送的三种模式3. QUdpSocket类的接口函数4. UDP单播和广播代码示例4.1 测试说明4.2 MainWindow.h4.3 MainWindow.cpp4.4 界面展示5. UDP组播代码示例5.1 组播的特性5.2 MainWindow.h5.3 MainWindow.cpp5.4 界面展示1. UDP通信概述 UDP是无连接、…...
【Java】properties 和 yml 的区别
文章目录properties和yml的区别① 定义和定位不同② 语法不同③ yml更好的配置多种数据类型④ yml可以跨语言⑤ 总结properties和yml的区别 这几天刚好看到Spring Boot当中有两种配置文件的方式,但是这两种配置方式有什么区别呢? properties和yml都是S…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
