https://www.shenmazong.com/album/1553219581379571712/1
前四节话术都要背
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.shenma2009</groupId>
<artifactId>server-shop-user</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>server-shop-user</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</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>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.shenma2009.ServerShopUserApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
spring.application.name=server-shop-user
# 应用服务 WEB 访问端口
server.port=9000
# Nacos认证信息
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=1912@a
# Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口
spring.cloud.nacos.discovery.server-addr=8.142.83.78:8848
# 注册到 nacos 的指定 namespace,默认为 public
spring.cloud.nacos.discovery.namespace=public
spring.cloud.nacos.discovery.group=zhouhaijun
## mybatis plus
#下面这些内容是为了让MyBatis映射
#指定Mybatis的Mapper文件
mybatis.mapper-locations=classpath:mappers/*xml
#指定Mybatis的实体目录
mybatis.type-aliases-package=com.shenma2009.pojo
# 数据库驱动:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源名称
spring.datasource.name=defaultDataSource
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/db_shop_2009a?autoReconnect= true&useUnicode= true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=123456
# SQL调试日志
logging.level.com.shenma2009.mapper=debug
# 逻辑删除配置
mybatis-plus.global-config.db-config.logic-delete-field=deleted
mybatis-plus.global-config.db-config.logic-not-delete-value=0
mybatis-plus.global-config.db-config.logic-delete-value=1
详细了解RBAC(Role-Based Access Control)
https://shenmazong.com/blog/1591262099727699968
package com.shenma2009.filter;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author 军哥
* @version 1.0
* @description: MybatisPlusConfig
* @date 2023/4/19 16:45
*/
@Configuration
@MapperScan("com.shenma2009.mapper*")
public class MybatisPlusConfig {
// 最新版
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
https://www.shenmazong.com/blog/1529682926714634240
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
package com.shenma2009.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @author 军哥
* @version 1.0
* @description: Knife4j 配置类
* @date 2022/5/26 9:56
*/
@Configuration
@EnableSwagger2
public class Knife4jConfiguration {
@Bean(value = "defaultApi2")
public Docket defaultApi2() {
String groupName="3.X版本";
Docket docket=new Docket(DocumentationType.OAS_30)
.apiInfo(new ApiInfoBuilder()
.title("这是knife4j API ")
.description("# 这里记录服务端所有的接口的入参,出参等等信息")
.termsOfServiceUrl("https://www.shenmazong.com")
.contact(new Contact("亮子说编程","https://www.shenmazong.com","3350996729@qq.com"))
.version("3.0")
.build())
//分组名称
.groupName(groupName)
.select()
//这里指定Controller扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.shenma2009.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
}
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.4</version>
</dependency>
package com.shenma2009.utils;
import io.jsonwebtoken.*;
import java.util.ArrayList;
import java.util.Date;
/**
* @author 军哥
* @version 1.0
* @description: JWT生成token工具类
* @date 2022/6/22 15:06
*/
public class TokenUtils {
public static int SUCCESS = 0;
public static int ERROR_SIGN = 1;
public static int ERROR_EXPIRE = 2;
public static int ERROR = 3;
private String key = "123456";
private Integer expireTime = 60;
private Claims claims = null;
JwtBuilder builder = null;
public TokenUtils() {
builder = Jwts.builder();
}
public static TokenUtils token() {
return new TokenUtils();
}
public TokenUtils setKey(String key) {
this.key = key;
return this;
}
public TokenUtils setExpire(Integer seconds) {
this.expireTime = seconds;
// 设置签发日期
builder.setIssuedAt(new Date());
// 设置过期时间
long now = System.currentTimeMillis();
long exp = now+1000*expireTime;
builder.setExpiration( new Date( exp ) );
return this;
}
public TokenUtils setClaim(String key, String value) {
builder.claim( key, value );
return this;
}
/**
* @description 生成最终token
* @author 军哥
* @date 2022/6/22 15:44
* @version 1.0
*/
public String makeToken() {
// 设置签名 使用HS256算法,并设置SecretKey(字符串)
builder.signWith(SignatureAlgorithm.HS256,key);
// 生成token
String token = builder.compact();
return token;
}
/**
* @description 存放多个Key-Value数据
* @author 军哥
* @date 2022/6/22 15:47
* @version 1.0
*/
public TokenUtils putKeyValues(String... keyValues) {
if(keyValues.length > 0) {
// 添加数据
ArrayList<String> stringPair = new ArrayList<>();
for(String kv:keyValues) {
// 添加键值对
stringPair.add(kv);
//
if(stringPair.size()>=2) {
builder.claim( stringPair.get(0),stringPair.get(1) );
stringPair.clear();
continue;
}
}
}
return this;
}
/**
* @description 添加键值对数据,然后生成token
* @author 军哥
* @date 2022/6/22 15:45
* @version 1.0
*/
public String createToken(String... keyValues) {
// 存放数据
if(keyValues.length > 0) {
// 添加数据
ArrayList<String> stringPair = new ArrayList<>();
for(String kv:keyValues) {
// 添加键值对
stringPair.add(kv);
//
if(stringPair.size()>=2) {
builder.claim( stringPair.get(0),stringPair.get(1) );
stringPair.clear();
continue;
}
}
}
//
// 设置签名 使用HS256算法,并设置SecretKey(字符串)
builder.signWith(SignatureAlgorithm.HS256,key);
// 生成token
String token = builder.compact();
return token;
}
public int parseToken(String token) {
try {
claims = Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(token)
.getBody();
return TokenUtils.SUCCESS;
}
catch (ExpiredJwtException e) {
System.out.println("token expired");
claims = e.getClaims();
return TokenUtils.ERROR_EXPIRE;
} catch (SignatureException e) {
System.out.println("token signature error");
return TokenUtils.ERROR_SIGN;
} catch (Exception e) {
System.out.println("token error");
return TokenUtils.ERROR;
}
}
public String getClaim(String key) {
if(claims == null) {
return null;
}
String value = (String)claims.get(key);
return value;
}
/**
* @description 测试工具类
* @author 军哥
* @date 2022/6/22 15:49
* @version 1.0
*/
public static void main(String[] args) {
String token = TokenUtils.token()
// 设置加密密码
.setKey("123456")
// 设置过期时间
.setExpire(60 * 30)
// 添加数据
.setClaim("id", "" + 666)
.setClaim("userName", "zhaoyun")
.putKeyValues("role", "admin", "permissions", "select,delete,insert")
// 生成token
.makeToken();
System.out.println("token="+token);
}
}
package com.shenma2009.config;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @author 军哥
* @version 1.0
* @description: 配置自定义redisTemplate
* @date 2022/2/9 11:23
*/
@Configuration
@EnableCaching
public class RedisConfig {
/**
* 配置自定义redisTemplate
* @return
*/
@Bean
RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
// 设置值(value)的序列化采用Jackson2JsonRedisSerializer。
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// 设置键(key)的序列化采用StringRedisSerializer。
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
git init
git remote add origin https://gitee.com/ywbingchuan/server-shop-2009.git
git push -u origin "master"