jianmu-springboot3-springalibabacloud pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
< modelVersion> 4.0.0</ modelVersion>
< groupId> org.jm</ groupId>
< artifactId> jianmu-springboot3-springalibabacloud</ artifactId>
< packaging> pom</ packaging>
< version> 1.0-SNAPSHOT</ version>
< modules>
< module> jm-gateway</ module>
< module> jm-apis</ module>
< module> jm-apis-common</ module>
< module> jm-dubbo-apis</ module>
</ modules>
< properties>
< java.version> 17</ java.version>
< maven.compiler.source> 17</ maven.compiler.source>
< maven.compiler.target> 17</ maven.compiler.target>
< project.build.sourceEncoding> UTF-8</ project.build.sourceEncoding>
< project.reporting.outputEncoding> UTF-8</ project.reporting.outputEncoding>
</ properties>
< dependencies>
< dependency>
< groupId> org.projectlombok</ groupId>
< artifactId> lombok</ artifactId>
< version> 1.18.26</ version>
</ dependency>
< dependency>
< groupId> com.alibaba.fastjson2</ groupId>
< artifactId> fastjson2-extension-spring6</ artifactId>
< version> 2.0.24</ version>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-logging</ artifactId>
< exclusions>
< exclusion>
< groupId> *</ groupId>
< artifactId> *</ artifactId>
</ exclusion>
</ exclusions>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-log4j2</ artifactId>
</ dependency>
</ dependencies>
< dependencyManagement>
< dependencies>
< dependency>
< groupId> com.baomidou</ groupId>
< artifactId> mybatis-plus-boot-starter</ artifactId>
< version> 3.5.3.1</ version>
</ dependency>
< dependency>
< groupId> com.mysql</ groupId>
< artifactId> mysql-connector-j</ artifactId>
< version> 8.0.32</ version>
</ dependency>
< dependency>
< groupId> com.baomidou</ groupId>
< artifactId> dynamic-datasource-spring-boot-starter</ artifactId>
< version> 3.5.2</ version>
</ dependency>
< dependency>
< groupId> com.alibaba</ groupId>
< artifactId> druid</ artifactId>
< version> 1.2.16</ version>
</ dependency>
< dependency>
< groupId> org.apache.commons</ groupId>
< artifactId> commons-lang3</ artifactId>
< version> 3.12.0</ version>
</ dependency>
< dependency>
< groupId> cn.dev33</ groupId>
< artifactId> sa-token-spring-boot3-starter</ artifactId>
< version> 1.34.0</ version>
</ dependency>
< dependency>
< groupId> cn.dev33</ groupId>
< artifactId> sa-token-reactor-spring-boot3-starter</ artifactId>
< version> 1.34.0</ version>
</ dependency>
< dependency>
< groupId> cn.dev33</ groupId>
< artifactId> sa-token-dao-redis-jackson</ artifactId>
< version> 1.34.0</ version>
</ dependency>
< dependency>
< groupId> org.apache.commons</ groupId>
< artifactId> commons-pool2</ artifactId>
< version> 2.11.1</ version>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-dependencies</ artifactId>
< version> 3.0.3</ version>
< type> pom</ type>
< scope> import</ scope>
</ dependency>
< dependency>
< groupId> com.alibaba.cloud</ groupId>
< artifactId> spring-cloud-alibaba-dependencies</ artifactId>
< version> 2022.0.0.0-RC1</ version>
< type> pom</ type>
< scope> import</ scope>
</ dependency>
< dependency>
< groupId> org.springframework.cloud</ groupId>
< artifactId> spring-cloud-dependencies</ artifactId>
< version> 2022.0.0</ version>
< type> pom</ type>
< scope> import</ scope>
</ dependency>
</ dependencies>
</ dependencyManagement>
</ project>
jm-apis-common pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
< parent>
< artifactId> jianmu-springboot3-springalibabacloud</ artifactId>
< groupId> org.jm</ groupId>
< version> 1.0-SNAPSHOT</ version>
</ parent>
< modelVersion> 4.0.0</ modelVersion>
< artifactId> jm-apis-common</ artifactId>
< packaging> pom</ packaging>
< modules>
< module> jm-apis-common-conf</ module>
< module> jm-apis-common-tool</ module>
< module> jm-apis-common-bean</ module>
</ modules>
< properties>
< maven.compiler.source> 17</ maven.compiler.source>
< maven.compiler.target> 17</ maven.compiler.target>
</ properties>
< dependencies>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-web</ artifactId>
< exclusions>
< exclusion>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-tomcat</ artifactId>
</ exclusion>
</ exclusions>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-undertow</ artifactId>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-data-redis</ artifactId>
</ dependency>
< dependency>
< groupId> org.apache.commons</ groupId>
< artifactId> commons-pool2</ artifactId>
</ dependency>
< dependency>
< groupId> cn.dev33</ groupId>
< artifactId> sa-token-spring-boot3-starter</ artifactId>
</ dependency>
< dependency>
< groupId> cn.dev33</ groupId>
< artifactId> sa-token-dao-redis-jackson</ artifactId>
</ dependency>
< dependency>
< groupId> com.github.xiaoymin</ groupId>
< artifactId> knife4j-openapi3-jakarta-spring-boot-starter</ artifactId>
< version> 4.0.0</ version>
</ dependency>
< dependency>
< groupId> com.baomidou</ groupId>
< artifactId> mybatis-plus-boot-starter</ artifactId>
< version> 3.5.3.1</ version>
</ dependency>
< dependency>
< groupId> com.mysql</ groupId>
< artifactId> mysql-connector-j</ artifactId>
< version> 8.0.32</ version>
</ dependency>
< dependency>
< groupId> com.alibaba</ groupId>
< artifactId> druid</ artifactId>
</ dependency>
< dependency>
< groupId> org.apache.commons</ groupId>
< artifactId> commons-lang3</ artifactId>
< version> 3.12.0</ version>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-test</ artifactId>
</ dependency>
</ dependencies>
</ project>
jm-apis-common jm-apis-common-conf
com.jm.common.conf
CommonsFastJsonConfig.java fastjson2配置类
package com. jm. common. conf. api ;
import com. alibaba. fastjson2. JSONReader ;
import com. alibaba. fastjson2. JSONWriter ;
import com. alibaba. fastjson2. support. config. FastJsonConfig ;
import com. alibaba. fastjson2. support. spring6. http. converter. FastJsonHttpMessageConverter ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. http. MediaType ;
import org. springframework. http. converter. HttpMessageConverter ;
import org. springframework. web. servlet. config. annotation. WebMvcConfigurer ;
import java. nio. charset. StandardCharsets ;
import java. util. Collections ;
import java. util. List ;
@Configuration
public class FastJsonConf implements WebMvcConfigurer {
@Override
public void configureMessageConverters ( List < HttpMessageConverter < ? > > converters) {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter ( ) ;
FastJsonConfig config = new FastJsonConfig ( ) ;
config. setDateFormat ( "yyyy-MM-dd HH:mm:ss" ) ;
config. setReaderFeatures ( JSONReader. Feature. FieldBased , JSONReader. Feature. SupportArrayToBean ) ;
config. setWriterFeatures ( JSONWriter. Feature. WriteMapNullValue , JSONWriter. Feature. PrettyFormat ) ;
converter. setFastJsonConfig ( config) ;
converter. setDefaultCharset ( StandardCharsets . UTF_8 ) ;
converter. setSupportedMediaTypes ( Collections . singletonList ( MediaType . APPLICATION_JSON ) ) ;
converters. add ( 0 , converter) ;
}
}
RedisConf.java 整合redis 的fastjson2
package com. jm. common. conf ;
import com. alibaba. fastjson2. support. spring6. data. redis. GenericFastJsonRedisSerializer ;
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 ;
@Configuration
public class RedisConf {
@Bean
public RedisTemplate redisTemplate ( RedisConnectionFactory redisConnectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate ( ) ;
redisTemplate. setConnectionFactory ( redisConnectionFactory) ;
GenericFastJsonRedisSerializer fastJsonRedisSerializer = new GenericFastJsonRedisSerializer ( ) ;
redisTemplate. setDefaultSerializer ( fastJsonRedisSerializer) ;
return redisTemplate;
}
}
整合Mybatis plus
package com. jm. common. conf. mybatis ;
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 ;
@Configuration
@MapperScan ( "com.jm.mapper*" )
public class MybatisPlusConf {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor ( ) {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor ( ) ;
interceptor. addInnerInterceptor ( new PaginationInnerInterceptor ( DbType . MYSQL ) ) ;
return interceptor;
}
@Bean
public SqlInjectorPlus sqlInjectorPlus ( ) {
return new SqlInjectorPlus ( ) ;
}
}
package com. jm. common. conf. mybatis ;
import org. apache. ibatis. type. LocalDateTimeTypeHandler ;
import org. springframework. stereotype. Component ;
import java. sql. ResultSet ;
import java. sql. SQLException ;
import java. sql. Timestamp ;
import java. time. LocalDateTime ;
@Component
public class MybatisLocalDateTimeTypeHandler extends LocalDateTimeTypeHandler {
@Override
public LocalDateTime getResult ( ResultSet rs, String columnName) throws SQLException {
Object object = rs. getObject ( columnName) ;
if ( object == null ) {
return null ;
}
if ( object instanceof Timestamp ) {
return ( ( Timestamp ) object) . toLocalDateTime ( ) ;
}
return super . getResult ( rs, columnName) ;
}
}
package com. jm. common. conf. mybatis ;
import com. baomidou. mybatisplus. core. handlers. MetaObjectHandler ;
import org. apache. ibatis. reflection. MetaObject ;
import org. springframework. stereotype. Component ;
import java. time. LocalDateTime ;
@Component
public class MyBatisPlusAutoFill implements MetaObjectHandler {
@Override
public void insertFill ( MetaObject metaObject) {
Object addTime = this . getFieldValByName ( "addTime" , metaObject) ;
if ( addTime == null ) {
this . setFieldValByName ( "addTime" , LocalDateTime . now ( ) , metaObject) ;
}
}
@Override
public void updateFill ( MetaObject metaObject) {
this . setFieldValByName ( "updateTime" , LocalDateTime . now ( ) , metaObject) ;
}
}
package com. jm. common. conf. mybatis ;
import com. baomidou. mybatisplus. core. injector. AbstractMethod ;
import com. baomidou. mybatisplus. core. injector. DefaultSqlInjector ;
import com. baomidou. mybatisplus. core. metadata. TableInfo ;
import java. util. List ;
public class SqlInjectorPlus extends DefaultSqlInjector {
@Override
public List < AbstractMethod > getMethodList ( Class < ? > mapperClass, TableInfo tableInfo) {
List < AbstractMethod > methods = super . getMethodList ( mapperClass, tableInfo) ;
return methods;
}
}
全局异常处理
package com. jm. common. conf ;
import cn. dev33. satoken. exception. NotLoginException ;
import com. jm. common. conf. api. Result ;
import com. jm. common. conf. api. ResultCode ;
import com. jm. common. conf. exception. ErrorException ;
import lombok. extern. slf4j. Slf4j ;
import org. springframework. beans. propertyeditors. CustomDateEditor ;
import org. springframework. validation. BindException ;
import org. springframework. validation. ObjectError ;
import org. springframework. web. bind. WebDataBinder ;
import org. springframework. web. bind. annotation. ControllerAdvice ;
import org. springframework. web. bind. annotation. ExceptionHandler ;
import org. springframework. web. bind. annotation. InitBinder ;
import org. springframework. web. bind. annotation. RestController ;
import java. text. SimpleDateFormat ;
import java. util. Date ;
@Slf4j
@RestController
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler ( value = BindException . class )
public Result < ? > methodArgumentNotValidException ( BindException e) {
ObjectError error = e. getBindingResult ( ) . getAllErrors ( ) . get ( 0 ) ;
log. error ( "error!" , e) ;
if ( log. isDebugEnabled ( ) ) {
e. fillInStackTrace ( ) ;
}
return Result . fail ( error. getDefaultMessage ( ) ) ;
}
@ExceptionHandler ( value = ErrorException . class )
public Result < ? > errorHandler ( ErrorException e) {
log. error ( "error!" , e) ;
if ( log. isDebugEnabled ( ) ) {
e. fillInStackTrace ( ) ;
}
return Result . fail ( e. getMessage ( ) . replaceAll ( "com.jianmu.exception.ErrorException: " , "" ) ) ;
}
@ExceptionHandler ( value = NotLoginException . class )
public Result < ? > errorHandler ( NotLoginException e) {
log. error ( "error!" , e) ;
if ( log. isDebugEnabled ( ) ) {
e. fillInStackTrace ( ) ;
}
return new Result < > ( ) . setCode ( ResultCode . UNAUTHORIZED . getCode ( ) )
. setInfo ( e. getMessage ( ) . replaceAll ( "com.jm.exception.NotLoginException: " , "" ) ) . setData ( false ) ;
}
@ExceptionHandler ( value = Exception . class )
public Result < ? > errorHandler ( Exception e) {
log. error ( "" , e) ;
if ( log. isDebugEnabled ( ) ) {
e. fillInStackTrace ( ) ;
}
if ( e. getMessage ( ) . contains ( "io.undertow.server.RequestTooBigException" ) ) {
return Result . fail ( "上传失败,请上传0~5M的图片" ) ;
}
return Result . fail ( "服务器出差了,请联系管理员!" ) ;
}
@InitBinder
public void initBinder ( WebDataBinder webDataBinder) throws BindException {
webDataBinder. registerCustomEditor ( Date . class , new CustomDateEditor ( new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss" ) , false ) ) ;
webDataBinder. close ( ) ;
}
}
undertow 自定义缓冲
package com. jm. common. conf ;
import io. undertow. server. DefaultByteBufferPool ;
import io. undertow. websockets. jsr. WebSocketDeploymentInfo ;
import org. springframework. boot. web. embedded. undertow. UndertowServletWebServerFactory ;
import org. springframework. boot. web. server. WebServerFactoryCustomizer ;
import org. springframework. stereotype. Component ;
@Component
public class UndertowConf implements WebServerFactoryCustomizer < UndertowServletWebServerFactory > {
@Override
public void customize ( UndertowServletWebServerFactory factory) {
factory. addDeploymentInfoCustomizers ( deploymentInfo -> {
WebSocketDeploymentInfo info = new WebSocketDeploymentInfo ( ) ;
info. setBuffers ( new DefaultByteBufferPool ( false , 1024 ) ) ;
deploymentInfo. addServletContextAttribute ( "io.undertow.websockets.jsr.WebSocketDeploymentInfo" , info) ;
} ) ;
}
}
接口统一响应注解
package com. jm. common. conf. api ;
import java. lang. annotation. * ;
@Retention ( RetentionPolicy . RUNTIME )
@Target ( { ElementType . TYPE , ElementType . METHOD } )
@Documented
public @interface ApiResult {
}
package com. jm. common. conf. api ;
public interface IErrorCode {
int getCode ( ) ;
String getInfo ( ) ;
String getApi ( ) ;
}
package com. jm. common. conf. api ;
import jakarta. annotation. Nonnull ;
import lombok. extern. slf4j. Slf4j ;
import org. springframework. core. MethodParameter ;
import org. springframework. http. MediaType ;
import org. springframework. http. converter. HttpMessageConverter ;
import org. springframework. http. server. ServerHttpRequest ;
import org. springframework. http. server. ServerHttpResponse ;
import org. springframework. web. bind. annotation. RestControllerAdvice ;
import org. springframework. web. servlet. mvc. method. annotation. ResponseBodyAdvice ;
@RestControllerAdvice
@Slf4j
public class ResponseResultHandler implements ResponseBodyAdvice < Object > {
@Override
public boolean supports ( MethodParameter returnType, @Nonnull Class < ? extends HttpMessageConverter < ? > > converterType) {
if ( returnType. getMethod ( ) != null ) {
return returnType. getMethod ( ) . isAnnotationPresent ( ApiResult . class ) ;
}
return false ;
}
@Override
public Object beforeBodyWrite ( Object body, @Nonnull MethodParameter parameter, @Nonnull MediaType type, @Nonnull Class < ? extends HttpMessageConverter < ? > > converterType,
@Nonnull ServerHttpRequest request, @Nonnull ServerHttpResponse response) {
return this . body ( body) ;
}
private Result < ? > body ( Object body) {
if ( body instanceof Boolean ) {
return ( Boolean ) body ? Result . ok ( ) : Result . fail ( ) ;
} else if ( body instanceof String ) {
return Result . ok ( String . valueOf ( body) ) ;
}
return Result . ok ( body) ;
}
}
package com. jm. common. conf. api ;
import lombok. AllArgsConstructor ;
import lombok. Data ;
import lombok. NoArgsConstructor ;
import lombok. experimental. Accessors ;
import java. io. Serializable ;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors ( chain = true )
public class Result < T > implements Serializable {
private int code;
private String info;
private T data;
public static Result < String > ok ( ) {
return new Result < > ( ResultCode . OK . getCode ( ) , ResultCode . OK . getInfo ( ) , null ) ;
}
public static < T > Result < T > ok ( T data) {
return new Result < > ( ResultCode . OK . getCode ( ) , ResultCode . OK . getInfo ( ) , data) ;
}
public static Result < String > fail ( ) {
return new Result < > ( ResultCode . FAIL . getCode ( ) , ResultCode . FAIL . getInfo ( ) , null ) ;
}
public static Result < String > fail ( String info) {
return new Result < > ( ResultCode . FAIL . getCode ( ) , info, null ) ;
}
@Override
public String toString ( ) {
return "{\"code\": " + this . getCode ( ) + ", \"info\": \"" + this . getInfo ( ) + "\", \"data\": \"" + this . getData ( ) + "\"}" ;
}
}
package com. jm. common. conf. api ;
public enum ResultCode implements IErrorCode {
OK ( 1 , "操作成功" ) ,
FAIL ( 0 , "操作失败" ) ,
UNAUTHORIZED ( - 1000 , "token已失效" ) ;
private final int code;
private final String info;
private String api;
ResultCode ( int code, String info) {
this . code = code;
this . info = info;
}
ResultCode ( int code, String info, String api) {
this . code = code;
this . info = info;
this . api = api;
}
@Override
public int getCode ( ) {
return code;
}
@Override
public String getInfo ( ) {
return info;
}
@Override
public String getApi ( ) {
return api;
}
}
package com. jm. common. conf. exception ;
public class ErrorException extends RuntimeException {
public ErrorException ( String message) {
super ( message) ;
}
public ErrorException ( String message, Throwable cause) {
super ( message, cause) ;
}
}
package com. jm. common. conf. constant ;
public class SysApiConstant {
private SysApiConstant ( ) { }
public static final String OPEN_API = "api/open/" ;
}
jm-user-api 登录接口
jm-datasource.yaml
spring :
datasource :
driver-class-name : com.mysql.cj.jdbc.Driver
username : root
password : root
url : jdbc: mysql: //localhost: 3306/db_jm_example? useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useUnicode=true&rewriteBatchedStatements=true
type : com.alibaba.druid.pool.DruidDataSource
mybatis-plus :
global-config :
db-config :
logic-delete-field : deleted
logic-delete-value : 1
logic-not-delete-value : 0
package com. jm. model ;
import com. baomidou. mybatisplus. annotation. TableName ;
import com. baomidou. mybatisplus. extension. activerecord. Model ;
import lombok. Data ;
import lombok. EqualsAndHashCode ;
import lombok. experimental. Accessors ;
import java. time. LocalDateTime ;
@Data
@Accessors ( chain = true )
@EqualsAndHashCode ( callSuper = false )
@TableName ( "s_sys_user" )
public class SysUser extends Model < SysUser > {
private Long id;
private String username;
private String password;
private Boolean deleted;
private LocalDateTime addTime;
private LocalDateTime updateTime;
}
package com. jm. mapper ;
import com. baomidou. mybatisplus. core. mapper. BaseMapper ;
import com. jm. model. SysUser ;
public interface SysUserMapper extends BaseMapper < SysUser > {
}
package com. jm. service. i ;
import com. baomidou. mybatisplus. extension. service. IService ;
import com. jm. model. SysUser ;
public interface SysUserService extends IService < SysUser > {
}
package com. jm. service. impl ;
import com. baomidou. mybatisplus. extension. service. impl. ServiceImpl ;
import com. jm. mapper. SysUserMapper ;
import com. jm. model. SysUser ;
import com. jm. service. i. SysUserService ;
import org. springframework. stereotype. Service ;
@Service
public class SysUserServiceImpl extends ServiceImpl < SysUserMapper , SysUser > implements SysUserService {
}
package com. jm. api ;
import cn. dev33. satoken. stp. StpUtil ;
import com. baomidou. mybatisplus. core. conditions. query. LambdaQueryWrapper ;
import com. jm. common. conf. api. ApiResult ;
import com. jm. common. conf. constant. SysApiConstant ;
import com. jm. common. conf. exception. ErrorException ;
import com. jm. model. SysUser ;
import com. jm. service. i. SysUserService ;
import com. jm. service. i. UserService ;
import io. swagger. v3. oas. annotations. Operation ;
import io. swagger. v3. oas. annotations. Parameter ;
import io. swagger. v3. oas. annotations. Parameters ;
import io. swagger. v3. oas. annotations. enums. ParameterIn ;
import io. swagger. v3. oas. annotations. tags. Tag ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. security. crypto. bcrypt. BCryptPasswordEncoder ;
import org. springframework. web. bind. annotation. PostMapping ;
import org. springframework. web. bind. annotation. RequestMapping ;
import org. springframework. web. bind. annotation. RestController ;
import java. util. UUID ;
@Tag ( name = "开放的登录接口" )
@RestController
@RequestMapping ( SysApiConstant . OPEN_API )
public class LoginApi {
private final SysUserService sysUserService;
private final UserService userService;
@Autowired
public LoginApi ( SysUserService sysUserService, UserService userService) {
this . sysUserService = sysUserService;
this . userService = userService;
}
@Operation ( summary = "登录" )
@Parameters ( { @Parameter ( name = "username" , description = "账号" , required = true , in = ParameterIn . QUERY ) ,
@Parameter ( name = "password" , description = "密码" , required = true , in = ParameterIn . QUERY ) } )
@PostMapping ( "/login/sys" )
@ApiResult
public String login ( String username, String password) {
this . userService. init ( ) ;
SysUser sysUser = this . sysUserService. getOne ( new LambdaQueryWrapper < SysUser > ( ) . eq ( SysUser :: getUsername , username) . last ( "limit 1" ) ) ;
if ( new BCryptPasswordEncoder ( ) . matches ( password, sysUser. getPassword ( ) ) ) {
StpUtil . login ( UUID . randomUUID ( ) ) ;
return StpUtil . getTokenValue ( ) ;
}
throw new ErrorException ( "登录失败" ) ;
}
public static void main ( String [ ] args) {
System . out. println ( new BCryptPasswordEncoder ( ) . encode ( "123456" ) ) ;
}
}
SET FOREIGN_KEY_CHECKS= 0 ;
DROP TABLE IF EXISTS ` s_sys_user` ;
CREATE TABLE ` s_sys_user` (
` id` bigint ( 20 ) NOT NULL AUTO_INCREMENT ,
` username` varchar ( 20 ) DEFAULT '' ,
` password` varchar ( 200 ) DEFAULT '' ,
` deleted` tinyint ( 1 ) DEFAULT '0' ,
` add_time` datetime DEFAULT NULL ,
` update_time` datetime DEFAULT NULL ,
PRIMARY KEY ( ` id` )
) ENGINE = InnoDB AUTO_INCREMENT = 2 DEFAULT CHARSET = utf8mb4;
INSERT INTO ` s_sys_user` VALUES ( '1' , 'kong' , '$2a$10$GLfuL5Bqxdl7LEQWTPbl4epfBcPb8A21pK1SE4lP7aK0jMcQmuhtW' , '0' , null , null ) ;
注意事项
springboo3 fastjson2 引入的包 为fastjson2-extension-spring6
knife4j-openapi3-jakarta-spring-boot-starter 4.0.0 存在bug
需要手动加上服务前端 /user/api/open/login/sys
sa-token 的包名为sa-token-spring-boot3-starter
完整代码请看项目git地址
https://gitee.com/sunuping/jianmu-example-jdk17.git