diff --git a/FAQ.md b/FAQ.md index b169ecb02f1ef92846be866aca0611b00e883e79..5fd20df38496ce61318ce38f9fc3bf670808a489 100644 --- a/FAQ.md +++ b/FAQ.md @@ -1,5 +1,6 @@ # FAQ +* Table "USERS" not found ```text Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "USERS" not found (candidates are: "user"); SQL statement: select user.age, user.birthDate, user.created_at, user.email, user.id, user.name @@ -10,6 +11,7 @@ limit ? [42103-232] 使用`H2`作为单元测试时,表名称大小写的问题,`from "user"` 这种写法是小写的表, `from user`是大写的表。 在`url`上添加`;DATABASE_TO_UPPER=FALSE`可以解决问题 +* EntityManager 没有初始化 ```text JPAQueryFactoryAutoConfiguration: Did not match: @@ -19,6 +21,7 @@ limit ? [42103-232] ``` 尽量不要在配置类上使用 `@ConditionalOnSingleCandidate` 或 `@ConditionalOnMissingBean`, spring会自动判断Bean初始化的顺序 +* [ERROR] Some problems were encountered while processing the POMs ```text [ERROR] [ERROR] Some problems were encountered while processing the POMs: [FATAL] Non-resolvable parent POM for io.gitee.yunjiao-source:spring-boot-examples:${revision}: The following artifacts could not be resolved: io.gitee.yunjiao-source:spring-boot-starter-parent:pom:${revision} (absent): io.gitee.yunjiao-source:spring-boot-starter-parent:pom:${revision} was not found in https://repo.maven.apache.org/maven2 during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of central has elapsed or updates are forced and 'parent.relativePath' points at no local POM @ line 5, column 13 @@ -40,6 +43,7 @@ flatten命令必须成功 mvn install ``` +* examples项目install时出现错误 ```text examples项目install时出现错误 @@ -62,9 +66,82 @@ examples项目install时出现错误 ``` 这是因为`QueryDsl SQL`编译时会生成Q类,这需要数据库连接,在`pom.xml`中修改数据库连接信息 +* Attempt to recreate a file for type yunjiao.springboot.example.querydsl.jpa.QOrder ```text -Attempt to recreate a file for type io.yunjiao.example.querydsl.jpa.QOrder +Attempt to recreate a file for type yunjiao.springboot.example.querydsl.jpa.QOrder ``` 通常在编译,安装项目时出现此异常,解决方法是`pom.xml` 文件中移除 `apt-maven-plugin` 即可 +* 运行`extension-querydsl`测试时异常 +```text +java.lang.IllegalArgumentException: org.hibernate.query.sqm.UnknownEntityException: Could not resolve root entity 'User' + + at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:143) + at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:167) + at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:173) + at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:886) + at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:796) + at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:143) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:364) + at jdk.proxy2/jdk.proxy2.$Proxy57.createQuery(Unknown Source) + at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:132) + at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:125) + at com.querydsl.jpa.impl.AbstractJPAQuery.fetch(AbstractJPAQuery.java:242) + at yunjiao.springboot.extension.querydsl.jpa.JPAQueryCurdExecutor.findList(JPAQueryCurdExecutor.java:393) + at yunjiao.springboot.extension.querydsl.jpa.JPAQueryCurdExecutor.findList(JPAQueryCurdExecutor.java:346) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360) + at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) + at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:380) + at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:728) + at yunjiao.springboot.extension.querydsl.jpa.JPAQueryCurdExecutor$$SpringCGLIB$$0.findList() + at yunjiao.springboot.extension.querydsl.jpa.JPAQueryRepositorySupportTest$DemoJPAQueryRepositorySupport.findUserByOrderStatus(JPAQueryRepositorySupportTest.java:193) + at yunjiao.springboot.extension.querydsl.jpa.JPAQueryRepositorySupportTest.whenFindUserByOrderStatus(JPAQueryRepositorySupportTest.java:124) + at java.base/java.lang.reflect.Method.invoke(Method.java:580) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) + at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) +Caused by: org.hibernate.query.sqm.UnknownEntityException: Could not resolve root entity 'User' + at org.hibernate.query.hql.internal.SemanticQueryBuilder.resolveRootEntity(SemanticQueryBuilder.java:2129) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitRootEntity(SemanticQueryBuilder.java:2059) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitRootEntity(SemanticQueryBuilder.java:277) + at org.hibernate.grammars.hql.HqlParser$RootEntityContext.accept(HqlParser.java:2814) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitEntityWithJoins(SemanticQueryBuilder.java:2029) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitFromClause(SemanticQueryBuilder.java:2016) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitQuery(SemanticQueryBuilder.java:1248) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitQuerySpecExpression(SemanticQueryBuilder.java:1040) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitQuerySpecExpression(SemanticQueryBuilder.java:277) + at org.hibernate.grammars.hql.HqlParser$QuerySpecExpressionContext.accept(HqlParser.java:2134) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitSimpleQueryGroup(SemanticQueryBuilder.java:1025) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitSimpleQueryGroup(SemanticQueryBuilder.java:277) + at org.hibernate.grammars.hql.HqlParser$SimpleQueryGroupContext.accept(HqlParser.java:2005) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitSelectStatement(SemanticQueryBuilder.java:492) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitStatement(SemanticQueryBuilder.java:451) + at org.hibernate.query.hql.internal.SemanticQueryBuilder.buildSemanticModel(SemanticQueryBuilder.java:324) + at org.hibernate.query.hql.internal.StandardHqlTranslator.translate(StandardHqlTranslator.java:71) + at org.hibernate.query.internal.QueryInterpretationCacheStandardImpl.createHqlInterpretation(QueryInterpretationCacheStandardImpl.java:145) + at org.hibernate.query.internal.QueryInterpretationCacheStandardImpl.resolveHqlInterpretation(QueryInterpretationCacheStandardImpl.java:132) + at org.hibernate.query.spi.QueryEngine.interpretHql(QueryEngine.java:54) + at org.hibernate.internal.AbstractSharedSessionContract.interpretHql(AbstractSharedSessionContract.java:832) + at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:878) + ... 26 more +``` + +测试用例JPAQueryRepositorySupportTest中,hibernate扫描路径需要修改 + +```text + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory() { +...... + em.setPackagesToScan("io.yunjiao"); + 改成 + em.setPackagesToScan("yunjiao.springboot"); +...... + return em; + }``` \ No newline at end of file diff --git a/README.md b/README.md index b51b70c2ef6b6c3c944648d4433ff47be2990ca5..4881293a3c1e38eaa6d0fc8ca2978189ed7ddede 100644 --- a/README.md +++ b/README.md @@ -2,29 +2,31 @@ 基于`Spring Boot`框架,集成其他框架开发的`Starter` -## 版本说明 +## 发布版本 -第一个的版本是`3.5.x.1`,前面两位是`Spring Boot`的版本,随着`Spring Boot`的版本升级而变。最后一位是本框架的版本,随着框架的扩展而增加,如:1,2,3,...x -不会因`Spring Boot`版本变动而变动。 +| 项目版本 | String Boot 版本 | +|--------------|----------------| +| <=0.3.0 | 3.0.13 | -如果需要 `Spring Boot` 3.5之前的包,请`fork`本项目,克隆代码,自己编译需要的版本。 + + +如果需要 `Spring Boot` 3.5之前的包,请`fork`本项目,克隆代码,自己编译需要的版本。例如编译`Spring Boot 3.5.4`的版本 +```shell +mvn clean install -P spring-boot-3.5.4 +``` ## 项目列表 | 项目 | 说明 | |---------------------------------------|-----------------------------------| -| spring-boot-autoconfigure | 自动配置 | -| spring-boot-dependencies | 项目依赖 | -| spring-boot-projects | 应用 | -| spring-boot-examples | 示例项目 | -| spring-querydsl | QueryDSL 集成 | -| spring-apijson | APIJSON 集成 | -| config | 配置 | -| spring-boot-starter-querydsl-jpa | QueryDSL JPA Spring Boot 启动器 | -| spring-boot-starter-querydsl-sql | QueryDSL SQL Spring Boot 启动器 | -| spring-boot-starter-hutool | Hutool Spring Boot 启动器 | -| spring-boot-starter-apijson-fastjson2 | APIJSON Fastjson2 Spring Boot 启动器 | -| spring-boot-starter-apijson-gson | APIJSON Gson Spring Boot 启动器 | +| autoconfigure | 自动配置 | +| dependencies | 项目依赖 | +| projects | 应用 | +| examples | 示例项目 | +| extensions | 扩展 | +| config | 配置 | +| starters | 启动器 | + ## 如何编译 @@ -65,8 +67,8 @@ mvn install ```text - io.gitee.yunjiao-source - spring-boot-starter-parent + io.gitee.yunjiao-source.spring-boot + starter-parent ${你需要的版本} @@ -74,8 +76,8 @@ mvn install - io.gitee.yunjiao-source - spring-boot-dependencies + io.gitee.yunjiao-source.spring-boot + dependencies ${你需要的版本} pom import @@ -86,11 +88,12 @@ mvn install ## 使用指南 -* spring-boot-starter-querydsl-jpa [使用指南](./spring-boot-starter-querydsl-jpa/README.md) [参考项目](./examples/example-querydsl-jpa) -* spring-boot-starter-querydsl-sql [使用指南](./spring-boot-starter-querydsl-sql/README.md) [参考项目](./examples/example-querydsl-sql) -* spring-boot-starter-hutool [使用指南](./spring-boot-starter-hutool/README.md) [参考项目](./examples/example-hutool) -* spring-boot-starter-apijson-fastjson2 [使用指南](./spring-boot-starter-apijson-fastjson2/README.md) [参考项目](./examples/example-apijson-fastjson2) -* spring-boot-starter-apijson-Gson [使用指南](./spring-boot-starter-apijson-gson/README.md) [参考项目](./examples/example-apijson-gons) +* starter-apijson-fastjson2 [使用指南](./doc/md/STARTER-APIJSON-FASTJSON2.md) +* starter-apijson-gson [使用指南](./doc/md/STARTER-APIJSON-GSON.md) +* starter-captcha [使用指南](./doc/md/STARTER-CAPTCHA.md) +* starter-id [使用指南](./doc/md/STARTER-ID.md) +* starter-querydsl-jpa [使用指南](./doc/md/STARTER-QUERYDSL-JPA.md) +* starter-querydsl-sql [使用指南](./doc/md/STARTER-QUERYDSL-SQL.md) ## 参考 diff --git a/autoconfigure/pom.xml b/autoconfigure/pom.xml index 9c68f5a5a4e811d6c29c7f9b224362169c29fe7a..83dac48858205e755c7aa8c30283a2311a48e5c8 100644 --- a/autoconfigure/pom.xml +++ b/autoconfigure/pom.xml @@ -3,7 +3,7 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot dependencies ${revision} ../dependencies/pom.xml @@ -28,21 +28,46 @@ - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extension-common true - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extension-apijson true - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extension-querydsl true + + io.gitee.yunjiao-source.spring-boot + extension-captcha + true + + + io.gitee.yunjiao-source.spring-boot + extension-id + true + + + com.google.guava + guava + provided + + + org.slf4j + slf4j-api + provided + + + org.projectlombok + lombok + provided + org.springframework spring-webmvc @@ -113,5 +138,12 @@ apijson-gson true + + + + org.springframework.boot + spring-boot-starter-test + test + \ No newline at end of file diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/hutool/HutoolProperties.java b/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/hutool/HutoolProperties.java deleted file mode 100644 index a1d03282cd508d293b3a6a0923e7cd3ccb53c6a7..0000000000000000000000000000000000000000 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/hutool/HutoolProperties.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.yunjiao.springboot.autoconfigure.hutool; - -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Hutool 配置属性 - * - * @author yangyunjiao - */ -@Data -@ConfigurationProperties(prefix = PropertyNameConsts.PROPERTY_PREFIX_HUTOOL) -public class HutoolProperties { - private Boolean snowflake; -} diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfiguration.java similarity index 76% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfiguration.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfiguration.java index 6753291fa106a32f12d1910f204283a41a9c8848..d59e506126892f0e819e3805141351998c722496 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfiguration.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfiguration.java @@ -1,11 +1,10 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; -import apijson.framework.APIJSONApplication; -import io.yunjiao.extension.apjson.annotation.ApijsonRest; -import io.yunjiao.extension.apjson.orm.IdKeyApijsonStrategy; -import io.yunjiao.extension.apjson.orm.IdKeyStrategy; -import io.yunjiao.extension.apjson.orm.NewIdStrategy; +import yunjiao.springboot.extension.apjson._APIJSON; +import yunjiao.springboot.extension.apjson.annotation.ApijsonRest; +import yunjiao.springboot.extension.apjson.orm.IdKeyApijsonStrategy; +import yunjiao.springboot.extension.apjson.orm.IdKeyStrategy; import jakarta.annotation.Nonnull; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; @@ -26,15 +25,15 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; */ @Slf4j @AutoConfiguration -@ConditionalOnClass({NewIdStrategy.class, APIJSONApplication.class}) +@ConditionalOnClass({_APIJSON.class}) @RequiredArgsConstructor @EnableConfigurationProperties({ApijsonProperties.class, ApijsonSqlProperties.class, ApijsonParserProperties.class, ApijsonVerifierProperties.class}) @Import({ - NewIdStrategyAutoConfiguration.class, - ApijsonInitAutoConfiguration.class, - Fastjson2ApplicationAutoConfiguration.class, - GsonApplicationAutoConfiguration.class + NewIdStrategyConfiguration.class, + ApijsonInitConfiguration.class, + Fastjson2ApplicationConfiguration.class, + GsonApplicationConfiguration.class }) public class ApijsonAutoConfiguration { /** @@ -60,7 +59,7 @@ public class ApijsonAutoConfiguration { IdKeyStrategy idKeyApijsonStrategy() { IdKeyStrategy bean = new IdKeyApijsonStrategy(); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Id Key APIJSON Strategy]"); + log.debug("Configure Bean [Id Key APIJSON Strategy: {}]", bean); } return bean; } diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurer.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurer.java similarity index 84% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurer.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurer.java index e501463ecfd15ec42d43a3d3a46f070b6bd7afc3..c42e8eabf7fc785a271dc4210d1ed99c92c14cab 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurer.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurer.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import apijson.orm.script.ScriptExecutor; @@ -6,7 +6,7 @@ import java.util.List; import java.util.Map; /** - * AbstractVerifier 用户自定义配置 + * AbstractVerifier 配置器 * * @author yangyunjiao */ diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonInitAutoConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonInitConfiguration.java similarity index 92% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonInitAutoConfiguration.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonInitConfiguration.java index 602ce3057e1d53df78cbfbcaeb17a750b940e63e..b637995f132e93dea9ea9ff48dc4642be02be45e 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonInitAutoConfiguration.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonInitConfiguration.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; @@ -15,14 +15,14 @@ import org.springframework.context.annotation.Configuration; @Slf4j @RequiredArgsConstructor @Configuration(proxyBeanMethods = false) -public class ApijsonInitAutoConfiguration { +public class ApijsonInitConfiguration { /** * {@link PostConstruct} 注解方法 */ @PostConstruct public void postConstruct() { - log.info("Apijson Init AutoConfiguration"); + log.info("Apijson Init Configuration"); } @@ -48,7 +48,7 @@ public class ApijsonInitAutoConfiguration { ApijsonInitializingBean bean = new ApijsonInitializingBean(parserProperties, verifierProperties, sqlProperties, sqlConfigConfigurers,apijsonVerifierConfigurers,apijsonFunctionParserConfigurers); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Apijson Initializing Bean]"); + log.debug("Configure Bean [Apijson Initializing Bean: {}]", bean); } return bean; } diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonInitializingBean.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonInitializingBean.java similarity index 98% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonInitializingBean.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonInitializingBean.java index 416a036e986d0bc2584b5d2f45f48188653cc4c9..0be497b91fa886ace3709d281f265e9656a25de6 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonInitializingBean.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonInitializingBean.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import apijson.framework.*; import lombok.RequiredArgsConstructor; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonParserProperties.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonParserProperties.java similarity index 94% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonParserProperties.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonParserProperties.java index d90e96ed9aebdf568ec4b55ea741dddd97b44a33..51c910d699866f28555af0b1821da4a168cc844f 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonParserProperties.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonParserProperties.java @@ -1,6 +1,6 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonProperties.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonProperties.java similarity index 95% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonProperties.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonProperties.java index 45b67dd0fe26a5059311a99a753074978a68e0f3..ab85bfba261bfb7c1ddb2f16d389e67e8a8e82fb 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonProperties.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonProperties.java @@ -1,6 +1,6 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurer.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurer.java similarity index 87% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurer.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurer.java index 61731b199215e0872e5f026daa7ff7491a4dfa84..c9d273289f25eac51d971df18678e14a55ef83a0 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurer.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurer.java @@ -1,10 +1,10 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import java.util.List; import java.util.Map; /** - * ApijsonSqlConfig 用户自定义配置 + * ApijsonSqlConfig 配置器 * * @author yangyunjiao */ diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlProperties.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlProperties.java similarity index 92% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlProperties.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlProperties.java index 44a6f3c6e7335b2a2fda1a9deb1526eadf722aaa..d919bedfedb16bf1459017394bd9f6061cf0785a 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlProperties.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlProperties.java @@ -1,7 +1,7 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; -import io.yunjiao.extension.apjson.util.ApijsonConsts; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.extension.apjson.util.ApijsonConsts; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonUtils.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonUtils.java similarity index 95% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonUtils.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonUtils.java index 8ecf7376234fe4351bec683dea5751e668b64c3e..d161e3e2aabe607745b348f6113b1db7bc19e186 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonUtils.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonUtils.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import apijson.RequestMethod; import apijson.framework.*; @@ -24,11 +24,13 @@ public final class ApijsonUtils { /** * 使用反射强制初始化 * - * @param clazz 类 + * @param clazzes 类 */ - public static void forceInit(Class clazz) { + public static void forceInit(Class... clazzes) { try { - Class.forName(clazz.getName(), true, clazz.getClassLoader()); + for (Class clazz : clazzes) { + Class.forName(clazz.getName(), true, clazz.getClassLoader()); + } } catch (ClassNotFoundException e) { throw new RuntimeException(e); } @@ -127,9 +129,9 @@ public final class ApijsonUtils { * @param configurers 配置器 */ public static void buildAPIJSONVerifierStatic(ApijsonVerifierProperties verifier, List configurers) { - APIJSONVerifier.IS_UPDATE_MUST_HAVE_ID_CONDITION = verifier.isUpdateMustHaveIdCondition(); - APIJSONVerifier.ENABLE_VERIFY_ROLE = verifier.isEnableVerifyRole(); - APIJSONVerifier.ENABLE_VERIFY_CONTENT = verifier.isEnableVerifyContent(); + AbstractVerifier.IS_UPDATE_MUST_HAVE_ID_CONDITION = verifier.isUpdateMustHaveIdCondition(); + AbstractVerifier.ENABLE_VERIFY_ROLE = verifier.isEnableVerifyRole(); + AbstractVerifier.ENABLE_VERIFY_CONTENT = verifier.isEnableVerifyContent(); APIJSONVerifier.ENABLE_VERIFY_COLUMN = verifier.isEnableVerifyColumn(); APIJSONVerifier.ENABLE_APIJSON_ROUTER = verifier.isEnableApijsonRouter(); diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurer.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurer.java similarity index 92% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurer.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurer.java index 4c2ff9d50c60a9f39aead7396bf32398d9734bfe..0ae797c864293fa74be989c400f7919f23156a0e 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurer.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurer.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import apijson.RequestMethod; import apijson.orm.Entry; @@ -9,7 +9,7 @@ import java.util.SortedMap; import java.util.regex.Pattern; /** - * AbstractVerifier 用户自定义配置 + * AbstractVerifier 配置器 * * @author yangyunjiao */ diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierProperties.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierProperties.java similarity index 86% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierProperties.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierProperties.java index 318765f429a86aebef399ba21a941c69212df0f4..1b1d309165787dd6351ccd908fd11af270e914d8 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierProperties.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierProperties.java @@ -1,6 +1,6 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/Fastjson2ApplicationAutoConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/Fastjson2ApplicationConfiguration.java similarity index 81% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/Fastjson2ApplicationAutoConfiguration.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/Fastjson2ApplicationConfiguration.java index 748777a7ef4957b97245b2e94953a141af0f2fe9..6bd0086b01aa8c0d7e07389bfe8995272b57ac73 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/Fastjson2ApplicationAutoConfiguration.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/Fastjson2ApplicationConfiguration.java @@ -1,17 +1,15 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; -import apijson.fastjson2.APIJSONApplication; -import io.yunjiao.extension.apjson.orm.IdKeyStrategy; -import io.yunjiao.extension.apjson.orm.NewIdStrategy; -import io.yunjiao.springboot.autoconfigure.apijson.condition.ApllicationCondition; -import io.yunjiao.springboot.autoconfigure.apijson.fastjson2.*; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.extension.apjson.orm.IdKeyStrategy; +import yunjiao.springboot.extension.apjson.orm.NewIdStrategy; +import yunjiao.springboot.autoconfigure.apijson.condition.ApllicationCondition; +import yunjiao.springboot.autoconfigure.apijson.fastjson2.*; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; @@ -28,17 +26,16 @@ import javax.sql.DataSource; @Slf4j @RequiredArgsConstructor @Configuration(proxyBeanMethods = false) -@AutoConfigureAfter({ApijsonInitAutoConfiguration.class}) +@AutoConfigureAfter({ApijsonInitConfiguration.class}) @Conditional(ApllicationCondition.OnFastjson2.class) -@ConditionalOnClass({APIJSONApplication.class}) -public class Fastjson2ApplicationAutoConfiguration { +public class Fastjson2ApplicationConfiguration { /** * {@link PostConstruct} 注解方法 */ @PostConstruct public void postConstruct() { - log.info("Fastjson2 Application Auto Configuration"); + log.info("Fastjson2 Application Configuration"); } /** @@ -53,7 +50,7 @@ public class Fastjson2ApplicationAutoConfiguration { ApijsonSqlProperties sqlProperties) { Fastjson2Creator bean = new Fastjson2Creator(dataSource, sqlProperties); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Fastjson2 Creator]"); + log.debug("Configure Bean [Fastjson2 Creator: {}]", bean); } return bean; } @@ -70,7 +67,7 @@ public class Fastjson2ApplicationAutoConfiguration { NewIdStrategy newIdStrategy) { Fastjson2SimpleCallback bean = new Fastjson2SimpleCallback(idKeyStrategy, newIdStrategy); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Fastjson2 Simple Callback]"); + log.debug("Configure Bean [Fastjson2 Simple Callback: {}]", bean); } return bean; } @@ -88,7 +85,7 @@ public class Fastjson2ApplicationAutoConfiguration { ApijsonProperties properties) { Fastjson2InitializingBean bean = new Fastjson2InitializingBean(fastjson2SimpleCallback, fastjson2Creator, properties); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Fastjson2 Initializing Bean]"); + log.debug("Configure Bean [Fastjson2 Initializing Bean: {}]", bean); } return bean; } @@ -98,7 +95,7 @@ public class Fastjson2ApplicationAutoConfiguration { */ @RequiredArgsConstructor @AutoConfiguration - @ConditionalOnProperty(name = {PropertyNameConsts.PROPERTY_PREFIX_APIJSON_RESTAPI_ENABLE}, + @ConditionalOnProperty(name = {PropertyNameConsts.PROPERTY_APIJSON_RESTAPI_ENABLE}, havingValue = "true", matchIfMissing = true) static @@ -114,7 +111,7 @@ public class Fastjson2ApplicationAutoConfiguration { Fastjson2RestController fastjson2RestController() { Fastjson2RestController bean = new Fastjson2RestController(properties); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Fastjson2 Rest Controller]"); + log.debug("Configure Bean [Fastjson2 Rest Controller: {}]", bean); } return bean; } @@ -128,7 +125,7 @@ public class Fastjson2ApplicationAutoConfiguration { Fastjson2EXtRestController fastjson2ExtRestController() { Fastjson2EXtRestController bean = new Fastjson2EXtRestController(); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Fastjson2 Rest Ext Controller]"); + log.debug("Configure Bean [Fastjson2 Rest Ext Controller: {}]", bean); } return bean; } diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/GsonApplicationAutoConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/GsonApplicationConfiguration.java similarity index 76% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/GsonApplicationAutoConfiguration.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/GsonApplicationConfiguration.java index 2a668da7ff09ebf1c2e65518f9562b46c7dd2543..9fff3d6c45ae39c6b7e1c33c945ddc48a1f70d0c 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/GsonApplicationAutoConfiguration.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/GsonApplicationConfiguration.java @@ -1,17 +1,15 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; -import apijson.gson.APIJSONApplication; -import io.yunjiao.extension.apjson.orm.IdKeyStrategy; -import io.yunjiao.extension.apjson.orm.NewIdStrategy; -import io.yunjiao.springboot.autoconfigure.apijson.condition.ApllicationCondition; -import io.yunjiao.springboot.autoconfigure.apijson.gson.*; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.extension.apjson.orm.IdKeyStrategy; +import yunjiao.springboot.extension.apjson.orm.NewIdStrategy; +import yunjiao.springboot.autoconfigure.apijson.condition.ApllicationCondition; +import yunjiao.springboot.autoconfigure.apijson.gson.*; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; @@ -28,17 +26,16 @@ import javax.sql.DataSource; @Slf4j @RequiredArgsConstructor @Configuration(proxyBeanMethods = false) -@AutoConfigureAfter({ApijsonInitAutoConfiguration.class}) +@AutoConfigureAfter({ApijsonInitConfiguration.class}) @Conditional(ApllicationCondition.OnGson.class) -@ConditionalOnClass({APIJSONApplication.class}) -public class GsonApplicationAutoConfiguration { +public class GsonApplicationConfiguration { /** * {@link PostConstruct} 注解方法 */ @PostConstruct public void postConstruct() { - log.info("Gson Application Auto Configuration"); + log.info("Gson Application Configuration"); } /** @@ -53,7 +50,7 @@ public class GsonApplicationAutoConfiguration { ApijsonSqlProperties sqlProperties) { GsonCreator bean = new GsonCreator(dataSource, sqlProperties); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Gson Creator]"); + log.debug("Configure Bean [Gson Creator: {}]", bean); } return bean; } @@ -70,7 +67,7 @@ public class GsonApplicationAutoConfiguration { NewIdStrategy newIdStrategy) { GsonSimpleCallback bean = new GsonSimpleCallback(idKeyStrategy, newIdStrategy); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Gson Simple Callback]"); + log.debug("Configure Bean [Gson Simple Callback: {}]", bean); } return bean; } @@ -88,7 +85,7 @@ public class GsonApplicationAutoConfiguration { ApijsonProperties properties) { GsonInitializingBean bean = new GsonInitializingBean(gsonSimpleCallback, gsonCreator, properties); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Gson Initializing Bean]"); + log.debug("Configure Bean [Gson Initializing Bean: {}]", bean); } return bean; } @@ -98,7 +95,7 @@ public class GsonApplicationAutoConfiguration { */ @RequiredArgsConstructor @AutoConfiguration - @ConditionalOnProperty(name = {PropertyNameConsts.PROPERTY_PREFIX_APIJSON_RESTAPI_ENABLE}, + @ConditionalOnProperty(name = {PropertyNameConsts.PROPERTY_APIJSON_RESTAPI_ENABLE}, havingValue = "true", matchIfMissing = true) static @@ -109,7 +106,7 @@ public class GsonApplicationAutoConfiguration { GsonRestController gsonRestController() { GsonRestController bean = new GsonRestController(properties); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Gson Rest Controller]"); + log.debug("Configure Bean [Gson Rest Controller: {}]", bean); } return bean; } @@ -118,7 +115,7 @@ public class GsonApplicationAutoConfiguration { GsonEXtRestController gsonEXtRestController() { GsonEXtRestController bean = new GsonEXtRestController(); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Gson Ext Rest Controller]"); + log.debug("Configure Bean [Gson Ext Rest Controller: {}]", bean); } return bean; } diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyAutoConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyConfiguration.java similarity index 82% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyAutoConfiguration.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyConfiguration.java index 7d1b801c5b06ee9bcbe00767e0130d967e3d4e1d..e8369a2fe3c208b8856939f7eea94321807f8a30 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyAutoConfiguration.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyConfiguration.java @@ -1,8 +1,7 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import cn.hutool.core.lang.Snowflake; -import io.yunjiao.extension.apjson.orm.*; -import io.yunjiao.springboot.autoconfigure.apijson.condition.NewIdStrategyCondition; +import yunjiao.springboot.autoconfigure.apijson.condition.NewIdStrategyCondition; import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -10,6 +9,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; +import yunjiao.springboot.extension.apjson.orm.*; /** * {@link NewIdStrategy}实现类自动配置 @@ -19,14 +19,14 @@ import org.springframework.context.annotation.Configuration; @Slf4j @Configuration(proxyBeanMethods = false) @ConditionalOnClass({NewIdStrategy.class}) -public class NewIdStrategyAutoConfiguration { +public class NewIdStrategyConfiguration { /** * {@link PostConstruct} 注解方法 */ @PostConstruct public void postConstruct() { - log.info("New Id Strategy Auto Configuration"); + log.info("New Id Strategy Configuration"); } @Bean @@ -34,7 +34,7 @@ public class NewIdStrategyAutoConfiguration { NewIdStrategy newIdDatabaseStrategy() { NewIdStrategy bean = new NewIdDatabaseStrategy(); if (log.isDebugEnabled()) { - log.debug("Configure Bean [New Id Database Strategy]"); + log.debug("Configure Bean [New Id Database Strategy: {}]", bean); } return bean; } @@ -44,7 +44,7 @@ public class NewIdStrategyAutoConfiguration { NewIdStrategy newIdSnowflakeStrategy(Snowflake snowflake) { NewIdStrategy bean = new NewIdSnowflakeStrategy(snowflake); if (log.isDebugEnabled()) { - log.debug("Configure Bean [New Id Snowflake Strategy]"); + log.debug("Configure Bean [New Id Snowflake Strategy: {}]", bean); } return bean; } @@ -54,7 +54,7 @@ public class NewIdStrategyAutoConfiguration { NewIdStrategy newIdTimestampStrategy() { NewIdStrategy bean = new NewIdTimestampStrategy(); if (log.isDebugEnabled()) { - log.debug("Configure Bean [New Id Timestamp Strategy]"); + log.debug("Configure Bean [New Id Timestamp Strategy: {}]", bean); } return bean; } @@ -64,7 +64,7 @@ public class NewIdStrategyAutoConfiguration { NewIdStrategy newIdUuidStrategy() { NewIdStrategy bean = new NewIdUuidStrategy(); if (log.isDebugEnabled()) { - log.debug("Configure Bean [New Id UUID Strategy]"); + log.debug("Configure Bean [New Id UUID Strategy: {}]", bean); } return bean; } @@ -75,7 +75,7 @@ public class NewIdStrategyAutoConfiguration { NewIdStrategy newIdCustomStrategy() { NewIdStrategy bean = new NewIdExceptionStrategy(); if (log.isDebugEnabled()) { - log.debug("Configure Bean [New Id Exception Strategy]"); + log.debug("Configure Bean [New Id Exception Strategy: {}]", bean); } return bean; } diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationCondition.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationCondition.java similarity index 77% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationCondition.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationCondition.java index 91f3bbc2f40d60af30c09f64ca2a0c0a39337e85..f853da393aceb9ee82b336f9fd0c0fdfdbb1f548 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationCondition.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationCondition.java @@ -1,9 +1,9 @@ -package io.yunjiao.springboot.autoconfigure.apijson.condition; +package yunjiao.springboot.autoconfigure.apijson.condition; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; -import io.yunjiao.springboot.autoconfigure.condition.EnumPropertyCondition; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; +import yunjiao.springboot.autoconfigure.condition.EnumPropertyCondition; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; /** * 应用程序类型条件 diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyCondition.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyCondition.java similarity index 86% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyCondition.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyCondition.java index 536fd8ddf2d4a5b6a6d38c0194cdd800a7e4ee1f..20e4abd5065e0736fce98325147da3b7f120fc8d 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyCondition.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyCondition.java @@ -1,8 +1,8 @@ -package io.yunjiao.springboot.autoconfigure.apijson.condition; +package yunjiao.springboot.autoconfigure.apijson.condition; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; -import io.yunjiao.springboot.autoconfigure.condition.EnumPropertyCondition; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; +import yunjiao.springboot.autoconfigure.condition.EnumPropertyCondition; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; /** * 主键生成策略条件 diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Creator.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Creator.java similarity index 88% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Creator.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Creator.java index 75447715f3c32c7e80cb1d2b2efa3a507498996e..05b06b5661c773a8057ea36e78061b9358c80e9a 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Creator.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Creator.java @@ -1,7 +1,7 @@ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2; +package yunjiao.springboot.autoconfigure.apijson.fastjson2; import apijson.fastjson2.*; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; +import yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; import lombok.RequiredArgsConstructor; import javax.sql.DataSource; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2EXtRestController.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2EXtRestController.java similarity index 98% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2EXtRestController.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2EXtRestController.java index e2e765c53af706d1a8eedc3cbb45d1d5b61c2241..9d66cc003eaaccf42d6e744a164f6b8f2bccb905 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2EXtRestController.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2EXtRestController.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2; +package yunjiao.springboot.autoconfigure.apijson.fastjson2; import apijson.Log; import apijson.StringUtil; @@ -9,10 +9,10 @@ import apijson.orm.exception.ConditionErrorException; import apijson.orm.exception.ConflictException; import apijson.orm.exception.NotExistException; import com.alibaba.fastjson2.JSONObject; -import io.yunjiao.extension.apjson.annotation.ApijsonRest; -import io.yunjiao.springboot.autoconfigure.apijson.fastjson2.model.Privacy; -import io.yunjiao.springboot.autoconfigure.apijson.fastjson2.model.User; -import io.yunjiao.springboot.autoconfigure.apijson.fastjson2.model.Verify; +import yunjiao.springboot.extension.apjson.annotation.ApijsonRest; +import yunjiao.springboot.autoconfigure.apijson.fastjson2.model.Privacy; +import yunjiao.springboot.autoconfigure.apijson.fastjson2.model.User; +import yunjiao.springboot.autoconfigure.apijson.fastjson2.model.Verify; import jakarta.servlet.http.HttpSession; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2FunctionParser.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2FunctionParser.java similarity index 86% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2FunctionParser.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2FunctionParser.java index f4bfa6b5f7ffa8f60e9ee38ea9cd776a1a2290d2..680d912cadb2a9e3ff71f6ec0f703bd2775fcd14 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2FunctionParser.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2FunctionParser.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2; +package yunjiao.springboot.autoconfigure.apijson.fastjson2; import apijson.fastjson2.APIJSONFunctionParser; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2InitializingBean.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2InitializingBean.java similarity index 89% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2InitializingBean.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2InitializingBean.java index 41d14054060dc6945433d7ef583999a6e5cab3d7..cd255625757bc746f87e26db39cdfcfcb2427259 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2InitializingBean.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2InitializingBean.java @@ -1,9 +1,9 @@ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2; +package yunjiao.springboot.autoconfigure.apijson.fastjson2; import apijson.Log; import apijson.fastjson2.*; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonUtils; +import yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; +import yunjiao.springboot.autoconfigure.apijson.ApijsonUtils; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.InitializingBean; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2ObjectParser.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2ObjectParser.java similarity index 96% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2ObjectParser.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2ObjectParser.java index 85a3080b0d61744cb42b654ad9f81c9292cbc9b4..ce84f46c6a521834c74f5fa6d583c4137e66feed 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2ObjectParser.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2ObjectParser.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2; +package yunjiao.springboot.autoconfigure.apijson.fastjson2; import apijson.RequestMethod; import apijson.fastjson2.APIJSONObjectParser; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Parser.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Parser.java similarity index 95% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Parser.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Parser.java index d9aa07c7814120b8e61f6740e597f09c5f473da6..6d7905a411f41c1a632a5602684593f2408dc762 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Parser.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Parser.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2; +package yunjiao.springboot.autoconfigure.apijson.fastjson2; import apijson.RequestMethod; import apijson.fastjson2.APIJSONObjectParser; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2RestController.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2RestController.java similarity index 89% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2RestController.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2RestController.java index 39f4bbc4b615a96c16393b2aa5dd5fd7d4c1a9bf..eab62df41ef05868ad013fdfe371eb1ba199074a 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2RestController.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2RestController.java @@ -1,10 +1,10 @@ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2; +package yunjiao.springboot.autoconfigure.apijson.fastjson2; import apijson.RequestMethod; import apijson.fastjson2.APIJSONController; import apijson.fastjson2.APIJSONParser; -import io.yunjiao.extension.apjson.annotation.ApijsonRest; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; +import yunjiao.springboot.extension.apjson.annotation.ApijsonRest; +import yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; import jakarta.servlet.http.HttpSession; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SimpleCallback.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SimpleCallback.java similarity index 90% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SimpleCallback.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SimpleCallback.java index 1a45d6a5d54c7a361fa60e03974b24d34a3ca73e..e04683c9d86e997884d498afd7729f1281ef91ca 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SimpleCallback.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SimpleCallback.java @@ -1,11 +1,11 @@ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2; +package yunjiao.springboot.autoconfigure.apijson.fastjson2; import apijson.RequestMethod; import apijson.fastjson2.APIJSONApplication; import apijson.orm.AbstractSQLConfig; import apijson.orm.SQLConfig; -import io.yunjiao.extension.apjson.orm.IdKeyStrategy; -import io.yunjiao.extension.apjson.orm.NewIdStrategy; +import yunjiao.springboot.extension.apjson.orm.IdKeyStrategy; +import yunjiao.springboot.extension.apjson.orm.NewIdStrategy; import lombok.RequiredArgsConstructor; import java.io.Serializable; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlConfig.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlConfig.java similarity index 81% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlConfig.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlConfig.java index 870f1f595ee5d7ccae0290b5f02aa9b63eea946a..64cf5de9df0a0fb12d8048d6ab98a6d0cfa3a22b 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlConfig.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlConfig.java @@ -1,7 +1,7 @@ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2; +package yunjiao.springboot.autoconfigure.apijson.fastjson2; import apijson.fastjson2.APIJSONSQLConfig; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; +import yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; import lombok.RequiredArgsConstructor; import java.io.Serializable; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlExecutor.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlExecutor.java similarity index 89% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlExecutor.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlExecutor.java index f392a53ca469d723b7f066cdff124950c50e3b81..7cda3f2a7ebbf357645ff67e74d40d288541622a 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlExecutor.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2SqlExecutor.java @@ -1,10 +1,10 @@ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2; +package yunjiao.springboot.autoconfigure.apijson.fastjson2; import apijson.fastjson2.APIJSONSQLExecutor; import apijson.orm.SQLConfig; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; -import io.yunjiao.extension.apjson.orm.SqlConnectProvider; +import yunjiao.springboot.extension.apjson.orm.SqlConnectProvider; import lombok.RequiredArgsConstructor; import javax.sql.DataSource; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Verifier.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Verifier.java similarity index 79% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Verifier.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Verifier.java index 6b9abe44674439ee7e3f9a1ee9cbd966e42bf67f..abfd7012f9c994bcab3e10b23d2feaa9b56bc81b 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Verifier.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/Fastjson2Verifier.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2; +package yunjiao.springboot.autoconfigure.apijson.fastjson2; import apijson.fastjson2.APIJSONVerifier; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Privacy.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Privacy.java similarity index 98% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Privacy.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Privacy.java index 6b751f6f98e2e7fa3f2485d38a7ba337c389c70d..f034b40d0f3dc417030dc150dbeae1abd151e1f9 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Privacy.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Privacy.java @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*/ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2.model; +package yunjiao.springboot.autoconfigure.apijson.fastjson2.model; import apijson.MethodAccess; import apijson.framework.BaseModel; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/User.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/User.java similarity index 98% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/User.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/User.java index f3a617680bb864dbbfa2dccb79d68c0edc8b4007..225bc5c6c13a0500c473e085441ebdc52bc7f0e3 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/User.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/User.java @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*/ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2.model; +package yunjiao.springboot.autoconfigure.apijson.fastjson2.model; import apijson.MethodAccess; import apijson.framework.BaseModel; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Verify.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Verify.java similarity index 97% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Verify.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Verify.java index 28f1a10c812a7dd2cba6377939d082a375ef37fe..0f01e478782e66c7e5b92d237f837601fccf08fb 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Verify.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/fastjson2/model/Verify.java @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*/ -package io.yunjiao.springboot.autoconfigure.apijson.fastjson2.model; +package yunjiao.springboot.autoconfigure.apijson.fastjson2.model; import apijson.MethodAccess; import apijson.framework.BaseModel; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonCreator.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonCreator.java similarity index 88% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonCreator.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonCreator.java index 2dfab5f7443d27957645b2d79c4abe80f90de246..ad86e858d468a7cbf7ceb9ac2b5de3a71b92a15d 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonCreator.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonCreator.java @@ -1,7 +1,7 @@ -package io.yunjiao.springboot.autoconfigure.apijson.gson; +package yunjiao.springboot.autoconfigure.apijson.gson; import apijson.gson.*; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; +import yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; import lombok.RequiredArgsConstructor; import javax.sql.DataSource; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonEXtRestController.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonEXtRestController.java similarity index 98% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonEXtRestController.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonEXtRestController.java index 3334a481130c606e10a3c85621b938aae1f3ebed..180ddb337fb1ea7efe51a1658425752bd080ea75 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonEXtRestController.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonEXtRestController.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson.gson; +package yunjiao.springboot.autoconfigure.apijson.gson; import apijson.Log; import apijson.StringUtil; @@ -10,11 +10,11 @@ import apijson.gson.JSONResponse; import apijson.orm.exception.ConditionErrorException; import apijson.orm.exception.ConflictException; import apijson.orm.exception.NotExistException; -import io.yunjiao.extension.apjson.annotation.ApijsonRest; -import io.yunjiao.extension.apjson.orm.GsonMap; -import io.yunjiao.springboot.autoconfigure.apijson.gson.model.Privacy; -import io.yunjiao.springboot.autoconfigure.apijson.gson.model.User; -import io.yunjiao.springboot.autoconfigure.apijson.gson.model.Verify; +import yunjiao.springboot.extension.apjson.annotation.ApijsonRest; +import yunjiao.springboot.extension.apjson.orm.GsonMap; +import yunjiao.springboot.autoconfigure.apijson.gson.model.Privacy; +import yunjiao.springboot.autoconfigure.apijson.gson.model.User; +import yunjiao.springboot.autoconfigure.apijson.gson.model.Verify; import jakarta.servlet.http.HttpSession; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonFunctionParser.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonFunctionParser.java similarity index 86% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonFunctionParser.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonFunctionParser.java index 8f4df51fc0ad3f5f7ff0f58763d97b44429fa0c3..69a74a26b6122738d91d161112246a969f904b3b 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonFunctionParser.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonFunctionParser.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson.gson; +package yunjiao.springboot.autoconfigure.apijson.gson; import apijson.gson.APIJSONFunctionParser; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonInitializingBean.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonInitializingBean.java similarity index 88% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonInitializingBean.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonInitializingBean.java index 2f7cbe5cde07b88c86c55b642e985d4ed28ccf85..06adb5b893af25d7e228e65daa409b24e3db9fcf 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonInitializingBean.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonInitializingBean.java @@ -1,8 +1,8 @@ -package io.yunjiao.springboot.autoconfigure.apijson.gson; +package yunjiao.springboot.autoconfigure.apijson.gson; import apijson.gson.*; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonUtils; +import yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; +import yunjiao.springboot.autoconfigure.apijson.ApijsonUtils; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.InitializingBean; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonObjectParser.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonObjectParser.java similarity index 96% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonObjectParser.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonObjectParser.java index 987781d79a12d5ab5bf6d946dcd995175a1b2061..5cc77011e0c65dd080a0f4ea6680c77de4e38d7d 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonObjectParser.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonObjectParser.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson.gson; +package yunjiao.springboot.autoconfigure.apijson.gson; import apijson.RequestMethod; import apijson.gson.APIJSONObjectParser; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonParser.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonParser.java similarity index 95% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonParser.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonParser.java index d88f511de989e52b395867c05b2410e55dcb84e2..cac03cbe7df8827950eb3f71608e5d4ffdfa4adf 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonParser.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonParser.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson.gson; +package yunjiao.springboot.autoconfigure.apijson.gson; import apijson.RequestMethod; import apijson.gson.APIJSONObjectParser; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonRestController.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonRestController.java similarity index 89% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonRestController.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonRestController.java index 395bde88c57ba5dc70d895de139d89a9f397d300..08c1e248bc336022970081c90228c8816598b5b5 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonRestController.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonRestController.java @@ -1,10 +1,10 @@ -package io.yunjiao.springboot.autoconfigure.apijson.gson; +package yunjiao.springboot.autoconfigure.apijson.gson; import apijson.RequestMethod; import apijson.gson.APIJSONController; import apijson.gson.APIJSONParser; -import io.yunjiao.extension.apjson.annotation.ApijsonRest; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; +import yunjiao.springboot.extension.apjson.annotation.ApijsonRest; +import yunjiao.springboot.autoconfigure.apijson.ApijsonProperties; import jakarta.servlet.http.HttpSession; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonSimpleCallback.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonSimpleCallback.java similarity index 89% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonSimpleCallback.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonSimpleCallback.java index ad2ddae349a98593e9ee59072b9917ae5ab0546b..9fd4f6899e61dee4ebc97bb964d0cb712fa2e25d 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonSimpleCallback.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonSimpleCallback.java @@ -1,12 +1,12 @@ -package io.yunjiao.springboot.autoconfigure.apijson.gson; +package yunjiao.springboot.autoconfigure.apijson.gson; import apijson.RequestMethod; import apijson.fastjson2.APIJSONApplication; import apijson.gson.APIJSONSQLConfig; import apijson.orm.AbstractSQLConfig; import apijson.orm.SQLConfig; -import io.yunjiao.extension.apjson.orm.IdKeyStrategy; -import io.yunjiao.extension.apjson.orm.NewIdStrategy; +import yunjiao.springboot.extension.apjson.orm.IdKeyStrategy; +import yunjiao.springboot.extension.apjson.orm.NewIdStrategy; import lombok.RequiredArgsConstructor; import java.io.Serializable; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlConfig.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlConfig.java similarity index 81% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlConfig.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlConfig.java index 2c64d9781fc91354cfcb7f0fe10b38dc4ef0a563..cdbd6c696bff93b2233f8aad9059f0a699dbc5bb 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlConfig.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlConfig.java @@ -1,7 +1,7 @@ -package io.yunjiao.springboot.autoconfigure.apijson.gson; +package yunjiao.springboot.autoconfigure.apijson.gson; import apijson.gson.APIJSONSQLConfig; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; +import yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; import lombok.RequiredArgsConstructor; import java.io.Serializable; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlExecutor.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlExecutor.java similarity index 89% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlExecutor.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlExecutor.java index 71db32dc9a3003e709e37a92d5fc97b20e600d8e..f0dd05bdbdeb8089817a1345908050c160827e8a 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlExecutor.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonSqlExecutor.java @@ -1,8 +1,8 @@ -package io.yunjiao.springboot.autoconfigure.apijson.gson; +package yunjiao.springboot.autoconfigure.apijson.gson; import apijson.gson.APIJSONSQLExecutor; import apijson.orm.SQLConfig; -import io.yunjiao.extension.apjson.orm.SqlConnectProvider; +import yunjiao.springboot.extension.apjson.orm.SqlConnectProvider; import lombok.RequiredArgsConstructor; import javax.sql.DataSource; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonVerifier.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonVerifier.java similarity index 80% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonVerifier.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonVerifier.java index ed1a38b16d99b601152efe3cc57705227ad97781..aeb276d6f3a60c4be67233b7f027c6f43e4731ab 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/GsonVerifier.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/GsonVerifier.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson.gson; +package yunjiao.springboot.autoconfigure.apijson.gson; import apijson.gson.APIJSONVerifier; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/model/Privacy.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/model/Privacy.java similarity index 97% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/model/Privacy.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/model/Privacy.java index e23f57930ed76a38685df94fcff2336549d987b8..ffed20c5e5ba73020253982be32e857d360f3c4e 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/model/Privacy.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/model/Privacy.java @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*/ -package io.yunjiao.springboot.autoconfigure.apijson.gson.model; +package yunjiao.springboot.autoconfigure.apijson.gson.model; import apijson.MethodAccess; import apijson.framework.BaseModel; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/model/User.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/model/User.java similarity index 97% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/model/User.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/model/User.java index 5a5881fa474deac0da4a2e51db8f3c6940b49908..1fbed7665ddfe4700b7cc52a038960a8a3751d7e 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/model/User.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/model/User.java @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*/ -package io.yunjiao.springboot.autoconfigure.apijson.gson.model; +package yunjiao.springboot.autoconfigure.apijson.gson.model; import apijson.MethodAccess; import apijson.framework.BaseModel; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/model/Verify.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/model/Verify.java similarity index 97% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/model/Verify.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/model/Verify.java index 19acb81ae0344747e020f0ea40e12dce2eae69c4..eb48d139d6d7e8686e3cde94c471a51d22b838d0 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/apijson/gson/model/Verify.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/apijson/gson/model/Verify.java @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*/ -package io.yunjiao.springboot.autoconfigure.apijson.gson.model; +package yunjiao.springboot.autoconfigure.apijson.gson.model; import apijson.MethodAccess; import apijson.framework.BaseModel; diff --git a/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/AnjiCaptchaConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/AnjiCaptchaConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..1eeae23b36cc92f3e01508536aa265295959d40c --- /dev/null +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/AnjiCaptchaConfiguration.java @@ -0,0 +1,178 @@ +package yunjiao.springboot.autoconfigure.captcha; + +import com.anji.captcha.model.common.Const; +import com.anji.captcha.service.CaptchaCacheService; +import com.anji.captcha.service.CaptchaService; +import com.anji.captcha.service.impl.CaptchaServiceFactory; +import com.anji.captcha.util.Base64Utils; +import com.anji.captcha.util.FileCopyUtils; +import com.anji.captcha.util.ImageUtils; +import jakarta.annotation.PostConstruct; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.util.StringUtils; +import yunjiao.springboot.extension.captcha.anji.BlockPuzzleCaptchaService; +import yunjiao.springboot.extension.captcha.anji.ClickWorkCaptchaService; +import yunjiao.springboot.extension.captcha.anji.RotatePluzzleCaptchaService; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * Anji 验证码自动配置 + * + * @author yangyunjiao + */ +@Slf4j +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass({CaptchaService.class}) +@EnableConfigurationProperties({AnjiCaptchaProperties.class}) +public class AnjiCaptchaConfiguration { + /** + * {@link PostConstruct} 注解方法 + */ + @PostConstruct + public void postConstruct() { + log.info("Anji Captcha Configuration"); + } + + @Bean + CaptchaCacheService captchaCacheService(){ + CaptchaCacheService service = CaptchaServiceFactory.getCache("local"); + if (log.isDebugEnabled()) { + log.debug("Configure Bean [Captcha Cache Service:{}]", service); + } + return service; + } + + @Bean + CaptchaService captchaService(AnjiCaptchaProperties properties) { + Properties config = new Properties(); + config.put(Const.CAPTCHA_WATER_MARK, properties.getWaterMark()); + config.put(Const.CAPTCHA_FONT_TYPE, properties.getClickWord().getFontType()); + config.put(Const.CAPTCHA_TYPE, "default"); + config.put(Const.CAPTCHA_INTERFERENCE_OPTIONS, properties.getBlockPuzzle().getInterferenceOptions()); + config.put(Const.ORIGINAL_PATH_JIGSAW, properties.getBlockPuzzle().getJigsaw()); + config.put(Const.ORIGINAL_PATH_PIC_CLICK, properties.getClickWord().getPicClick()); + config.put(Const.CAPTCHA_SLIP_OFFSET, properties.getBlockPuzzle().getSlipOffset()); + config.put(Const.CAPTCHA_AES_STATUS, "false"); + config.put(Const.CAPTCHA_WATER_FONT, properties.getWaterFont()); + + + config.put(Const.CAPTCHA_FONT_SIZE, properties.getClickWord().getFontSize()); + config.put(Const.CAPTCHA_FONT_STYLE, properties.getClickWord().getFontStyle().getMapping()); + config.put(Const.CAPTCHA_WORD_COUNT, properties.getClickWord().getClickWordCount()); + + fixBugCache(config); + fixBugResource(config); + + // 加载自定义 + initJigsawResource(properties.getBlockPuzzle().getJigsaw()); + initPicClickResource(properties.getClickWord().getPicClick()); + CaptchaService service = CaptchaServiceFactory.getInstance(config); + if (log.isDebugEnabled()) { + log.debug("Configure Bean [Captcha Service:{}]", service); + } + return service; + } + + /** + * 初始化时,加载默认资源执行多次, 资源重复加载。解决: 手工加载默认资源 + * + * @param config 必须值 + */ + private void fixBugResource(Properties config) { + // 框架问题: 方向反了 + config.put(Const.CAPTCHA_INIT_ORIGINAL, "true"); + + // 加载默认资源 + ImageUtils.cacheImage(null, null, null); + } + + /** + * 初始化缓存回执行多次,造成CacheUtil中任务泄露。解决:停用任务,手工删除缓存 + * + * @param config 必须值 + */ + private void fixBugCache(Properties config) { + config.put(Const.CAPTCHA_CACHETYPE, "local"); + config.put(Const.CAPTCHA_TIMING_CLEAR_SECOND, "0"); + } + + @Bean + yunjiao.springboot.extension.common.captcha.CaptchaService blockPuzzleCaptchaService(CaptchaService captchaService, + CaptchaCacheService captchaCacheService, + AnjiCaptchaProperties properties) { + BlockPuzzleCaptchaService service = new BlockPuzzleCaptchaService(captchaService, + captchaCacheService, + properties.getBlockPuzzle().getSlipOffset()); + if (log.isDebugEnabled()) { + log.debug("Configure Bean [Block Puzzle CaptchaService:{}]", service); + } + return service; + } + + @Bean + yunjiao.springboot.extension.common.captcha.CaptchaService clickWorkCaptchaService(CaptchaService captchaService, + CaptchaCacheService captchaCacheService, + AnjiCaptchaProperties properties) { + ClickWorkCaptchaService service = new ClickWorkCaptchaService(captchaService, + captchaCacheService, + properties.getBlockPuzzle().getSlipOffset()); + if (log.isDebugEnabled()) { + log.debug("Configure Bean [Click Work CaptchaService:{}]", service); + } + return service; + } + + @Bean + yunjiao.springboot.extension.common.captcha.CaptchaService rotatePluzzleCaptchaService(CaptchaService captchaService, + CaptchaCacheService captchaCacheService) { + RotatePluzzleCaptchaService service = new RotatePluzzleCaptchaService(captchaService, + captchaCacheService); + if (log.isDebugEnabled()) { + log.debug("Configure Bean [Rotate Pluzzle CaptchaService:{}]", service); + } + return service; + } + + private void initJigsawResource(String jigsaw) { + if (StringUtils.hasText(jigsaw) && jigsaw.startsWith("classpath")) { + ImageUtils.cacheBootImage(getResourcesImagesFile(jigsaw + "/original/*.png"), + getResourcesImagesFile(jigsaw + "/slidingBlock/*.png"), + Collections.emptyMap()); + } + } + + private void initPicClickResource(String picClick) { + if (StringUtils.hasText(picClick) && picClick.startsWith("classpath")) { + ImageUtils.cacheBootImage(Collections.emptyMap(), Collections.emptyMap(), + getResourcesImagesFile(picClick + "/*.png")); + } + } + + public Map getResourcesImagesFile(String path) { + Map imgMap = new HashMap<>(); + ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + try { + Resource[] resources = resolver.getResources(path); + for (Resource resource : resources) { + byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream()); + String string = Base64Utils.encodeToString(bytes); + String filename = resource.getFilename(); + imgMap.put(filename, string); + } + } catch (Exception e) { + log.error("初始化Anji验证码码资源异常", e); + } + return imgMap; + } +} diff --git a/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/AnjiCaptchaProperties.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/AnjiCaptchaProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..d141df3948823aec57420a42db7a5e815c972062 --- /dev/null +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/AnjiCaptchaProperties.java @@ -0,0 +1,95 @@ +package yunjiao.springboot.autoconfigure.captcha; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.extension.common.model.FontStyle; + +/** + * anji验证码属性 + * + * @author yangyunjiao + */ +@Data +@ConfigurationProperties(prefix = PropertyNameConsts.PROPERTY_PREFIX_CAPTCHA_ANJI) +public class AnjiCaptchaProperties { + /** + * 右下角水印文字(我的水印). + */ + private String waterMark = "我的水印"; + + /** + * 右下角水印字体(文泉驿正黑). + */ + private String waterFont = "WenQuanZhengHei.ttf"; + + /** + * 滑动验证码配置 + */ + @NestedConfigurationProperty + private BlockPuzzleOptions blockPuzzle = new BlockPuzzleOptions(); + + /** + * 点选文字验证码配置 + */ + @NestedConfigurationProperty + private ClickWordOptions clickWord = new ClickWordOptions(); + + /** + * 滑动验证码 属性 + */ + @Data + public static class BlockPuzzleOptions { + /** + * 滑动拼图底图路径. + */ + private String jigsaw = ""; + + /** + * 校验滑动拼图允许误差偏移量(默认5像素). + */ + private Integer slipOffset = 5; + + /** + * 滑块干扰项(0/1/2) + */ + private Integer interferenceOptions = 0; + } + + /** + * 点选文字验证码 属性 + */ + @Data + public static class ClickWordOptions { + /** + * 点选文字底图路径. + */ + private String picClick = ""; + + /** + * 点选文字验证码的文字字体(文泉驿正黑). + */ + private String fontType = "WenQuanZhengHei.ttf"; + + /** + * 点选字体样式 + */ + private FontStyle fontStyle = FontStyle.bold; + + /** + * 点选字体大小 + */ + private Integer fontSize = 25; + + /** + * 点选文字个数 + */ + private Integer clickWordCount = 4; + + /** + * 校验拼图允许误差(默认13像素). + */ + private Integer slipOffset = 13; + } +} diff --git a/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/CaptchaAutoConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/CaptchaAutoConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..1a9ea9461b4e5799f04deaba7f5cf8b1548c4860 --- /dev/null +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/CaptchaAutoConfiguration.java @@ -0,0 +1,49 @@ +package yunjiao.springboot.autoconfigure.captcha; + +import jakarta.annotation.PostConstruct; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import yunjiao.springboot.extension.captcha._Captcha; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaService; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 验证码 自动配置 + * + * @author yangyunjiao + */ +@Slf4j +@AutoConfiguration +@ConditionalOnClass({_Captcha.class}) +@Import({ + HutoolCaptchaConfiguration.class, + AnjiCaptchaConfiguration.class +}) +public class CaptchaAutoConfiguration { + /** + * {@link PostConstruct} 注解方法 + */ + @PostConstruct + public void postConstruct() { + log.info("Captcha Auto Configuration"); + } + + @Bean + CaptchaServiceFactory captchaServiceFactory(ObjectProvider captchaServices) { + Map services = + captchaServices.stream() + .collect(Collectors.toMap(CaptchaService::getCategory, m -> m)); + CaptchaServiceFactory factory = new CaptchaServiceFactory(services); + if (log.isDebugEnabled()) { + log.debug("Configure Bean [Captcha Service Factory: {}]", factory); + } + return factory; + } +} diff --git a/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/CaptchaServiceFactory.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/CaptchaServiceFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..4e47897ee173042a0f1a156bd79dd6d317b435aa --- /dev/null +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/CaptchaServiceFactory.java @@ -0,0 +1,45 @@ +package yunjiao.springboot.autoconfigure.captcha; + +import yunjiao.springboot.extension.captcha.CaptchaException; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaService; +import yunjiao.springboot.extension.common.lang.EnumCache; + +import java.util.Map; + +/** + * 验证码服务工厂 + * + * @author yangyunjiao + */ +public record CaptchaServiceFactory(Map services) { + + /** + * 根据分类代码,查找验证码服务 + * + * @param categoryName 分类名称,必须值 + * @return 实例 + */ + public CaptchaService findService(String categoryName) { + CaptchaCategory category = EnumCache.findByName(CaptchaCategory.class, categoryName); + if (category == null) { + throw new CaptchaException("验证码分类代码不存在,名称是:" + categoryName); + } + return findService(category); + } + + /** + * 根据分类,查找验证码服务 + * + * @param category 分类 + * @return 实例 + */ + public CaptchaService findService(CaptchaCategory category) { + CaptchaService service = services.get(category); + if (service == null) { + throw new CaptchaException("根据分类查找验证码服务未找到, 分类是:" + category); + } + + return service; + } +} diff --git a/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/HutoolCaptchaConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/HutoolCaptchaConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..ec5835e2e0f8b8b11aa84928b924c7afbd937cc3 --- /dev/null +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/HutoolCaptchaConfiguration.java @@ -0,0 +1,142 @@ +package yunjiao.springboot.autoconfigure.captcha; + +import cn.hutool.captcha.ICaptcha; +import cn.hutool.core.lang.Assert; +import jakarta.annotation.PostConstruct; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import yunjiao.springboot.extension.captcha.hutool.*; +import yunjiao.springboot.extension.common.captcha.CaptchaService; + +import java.awt.*; + +/** + * Hutool验证码配置 + * + * @author yangyunjiao + */ +@Slf4j +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass({ICaptcha.class}) +@EnableConfigurationProperties({HutoolCaptchaProperties.class}) +public class HutoolCaptchaConfiguration { + /** + * {@link PostConstruct} 注解方法 + */ + @PostConstruct + public void postConstruct() { + log.info("Hutool Captcha Configuration"); + } + + @Bean + CaptchaService lineCaptchaService(HutoolCaptchaProperties properties) { + HutoolCaptchaProperties.DrawingOptions options = properties.getLine(); + validate(options); + Font font = createFont(options.getFont()); + + LineCaptchaBuilder lcb = new LineCaptchaBuilder(); + fillBuilder(lcb, options); + + LineCaptchaService service = new LineCaptchaService(lcb); + if (log.isDebugEnabled()) { + log.debug("Configure Bean [Line Captcha Service:{}]", service); + } + return service; + } + + @Bean + CaptchaService circleCaptchaService(HutoolCaptchaProperties properties) { + HutoolCaptchaProperties.DrawingOptions options = properties.getCircle(); + validate(options); + + CircleCaptchaBuilder ccb = new CircleCaptchaBuilder(); + fillBuilder(ccb, options); + + CircleCaptchaService service = new CircleCaptchaService(ccb); + if (log.isDebugEnabled()) { + log.debug("Configure Bean [Circle Captcha Service:{}]", service); + } + return service; + } + + @Bean + CaptchaService sheareCaptchaService(HutoolCaptchaProperties properties) { + HutoolCaptchaProperties.DrawingOptions options = properties.getShear(); + validate(options); + + ShearCaptchaBuilder scb = new ShearCaptchaBuilder(); + fillBuilder(scb, options); + + ShearCaptchaService service = new ShearCaptchaService(scb); + if (log.isDebugEnabled()) { + log.debug("Configure Bean [Shear Captcha Service:{}]", service); + } + return service; + } + + + @Bean + CaptchaService gifCaptchaService(HutoolCaptchaProperties properties) { + HutoolCaptchaProperties.GifDrawingOptions options = properties.getGif(); + validate(options); + Assert.isTrue(options.getQuality() >= 1 && options.getQuality() <= 20, "验证码配置属性‘quality‘值必须在[1, 20]之间"); + Assert.isTrue(options.getRepeat() >= 0, "验证码配置属性‘repeat‘值必须大于0"); + Assert.isTrue(options.getMinColor() >= 0 && options.getMinColor() <= 255, "验证码配置属性‘minColor‘值必须在[0, 255]之间"); + Assert.isTrue(options.getMaxColor() >= 0 && options.getMaxColor() <= 255, "验证码配置属性‘maxColor‘值必须在[0, 255]之间"); + + GifCaptchaBuilder gcb = new GifCaptchaBuilder(); + fillBuilder(gcb, options); + gcb.setQuality(options.getQuality()); + gcb.setRepeat(options.getRepeat()); + gcb.setMinColor(options.getMinColor()); + gcb.setMaxColor(options.getMaxColor()); + + GifCaptchaService service = new GifCaptchaService(gcb); + if (log.isDebugEnabled()) { + log.debug("Configure Bean [Gif Captcha Service:{}]", service); + } + return service; + } + + private void validate(HutoolCaptchaProperties.DrawingOptions drawing) { + Assert.isTrue(drawing.getWidth() > 0, "验证码配置属性‘width‘值必须大于0"); + Assert.isTrue(drawing.getHeight() > 0, "验证码配置属性‘height‘值必须大于0"); + Assert.isTrue(drawing.getInterfereCount() > 0, "验证码配置属性‘interfereCount‘值必须大于0"); + + Float transparency = drawing.getTransparency(); + if (transparency != null) { + Assert.isTrue(drawing.getTransparency() >= 0 && drawing.getTransparency() <= 1, "验证码配置属性‘transparency‘值必须在[0, 1]之间"); + } + Assert.isTrue(drawing.getFuzziness() >= 0 && drawing.getFuzziness() <= 30, "验证码配置属性‘fuzziness‘值必须在[0, 30]之间"); + + + HutoolCaptchaProperties.CodeOptions code = drawing.getCode(); + Assert.isTrue(code.getLength() > 0, "验证码配置属性‘code.length‘值必须大于0"); + + HutoolCaptchaProperties.FontOptions font = drawing.getFont(); + Assert.isTrue(font.getSize() > 0, "验证码配置属性‘font.size‘值必须大于0"); + } + + private void fillBuilder(AbstractCaptchaBuilder builder, HutoolCaptchaProperties.DrawingOptions options) { + Font font = createFont(options.getFont()); + + builder.setWidth(options.getWidth()); + builder.setHeight(options.getHeight()); + builder.setInterfereCount(options.getInterfereCount()); + builder.setBackgroundColor(options.getBackgroundColor()); + builder.setFuzziness(options.getFuzziness()); + builder.setValidIgnoreCase(options.getValidIgnoreCase()); + builder.setFont(font); + + HutoolCaptchaProperties.CodeOptions code = options.getCode(); + builder.setGenerator(code.getGenerator().apply(code.getLength())); + } + + @SuppressWarnings({"all"}) + private Font createFont(HutoolCaptchaProperties.FontOptions options) { + return new Font(options.getName(), options.getStyle().getMapping(), options.getSize()); + } +} diff --git a/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/HutoolCaptchaProperties.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/HutoolCaptchaProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..09cf3a7651439fb2f3fa301ac633e1416ef757d8 --- /dev/null +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/captcha/HutoolCaptchaProperties.java @@ -0,0 +1,248 @@ +package yunjiao.springboot.autoconfigure.captcha; + +import yunjiao.springboot.extension.captcha.hutool.CodeGeneratorType; +import yunjiao.springboot.extension.common.model.ColorType; +import yunjiao.springboot.extension.common.model.FontStyle; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; + +/** + * Hutool验证码属性 + * + * @author yangyunjiao + */ +@Data +@ConfigurationProperties(prefix = PropertyNameConsts.PROPERTY_PREFIX_CAPTCHA_HUTOOL) +public class HutoolCaptchaProperties { + /** + * 线段干扰的验证码 + */ + @NestedConfigurationProperty + private DrawingOptions line = DrawingOptions.of(new DrawingOptions(), 250, 50, 60, + ColorType.white, null, 2, true, null, FontStyle.plain, 36, + CodeGeneratorType.numAndChar, 5); + + /** + * 圆圈干扰验证码 + */ + @NestedConfigurationProperty + private DrawingOptions circle = DrawingOptions.of(new DrawingOptions(), 250, 50, 30, + ColorType.white, null, 2, true, null, FontStyle.plain, 36, + CodeGeneratorType.numAndChar, 5); + + /** + * 扭曲干扰验证码 + */ + @NestedConfigurationProperty + private DrawingOptions shear = DrawingOptions.of(new DrawingOptions(), 250, 50, 4, + ColorType.white, null, 2, true, null, FontStyle.plain, 36, + CodeGeneratorType.numAndChar, 5); + + /** + * Gif验证码 + */ + @NestedConfigurationProperty + private GifDrawingOptions gif = GifDrawingOptions.of(new GifDrawingOptions(), 250, 50, 10, + ColorType.white, null, 2, true, null, FontStyle.plain, 36, + CodeGeneratorType.numAndChar, 5, 10, 0, 0, 255); + + @Data + @EqualsAndHashCode(callSuper = true) + public static class GifDrawingOptions extends DrawingOptions { + /** + * 量化器取样间隔, 1 ~ 20 值之间 - 默认是10ms + */ + private Integer quality; + + /** + * 帧循环次数,默认是 0, 意味着无限循环 + */ + private Integer repeat; + + /** + * 设置随机颜色时,最小的取色范围 + */ + private Integer minColor; + + /** + * 设置随机颜色时,最大的取色范围 + */ + private Integer maxColor; + + + public static GifDrawingOptions of(GifDrawingOptions options, int width, int height, int interfereCount, + ColorType backgroundColor, Float transparency, Integer fuzziness, Boolean validIgnoreCase, + String fontName, FontStyle fontStyle, Integer fontSize, + CodeGeneratorType generator, int length, + Integer quality, Integer repeat, Integer minColor, Integer maxColor) { + DrawingOptions.of(options, width, height, interfereCount, backgroundColor, transparency, fuzziness, validIgnoreCase, fontName, + fontStyle, fontSize, generator, length); + options.setQuality(quality); + options.setRepeat(repeat); + options.setMinColor(minColor); + options.setMaxColor(maxColor); + return options; + } + } + + /** + * 绘图选项 + */ + @Data + public static class DrawingOptions { + /** + * 图片的宽度 + */ + private Integer width; + + /** + * 图片的高度 + */ + private Integer height; + + /** + * 验证码干扰元素个数(干扰线宽度) + */ + private Integer interfereCount; + + /** + * 背景色 + */ + private ColorType backgroundColor; + + /** + * 文字透明度,取值0~1,1表示不透明 + */ + private Float transparency; + + /** + * 模糊度(0 - 30) + */ + private Integer fuzziness; + + /** + * 校验时忽略大小写 + */ + private Boolean validIgnoreCase; + + /** + * 字体选项 + */ + @NestedConfigurationProperty + private FontOptions font; + + /** + * 码选项 + */ + @NestedConfigurationProperty + private CodeOptions code; + + /** + * 创建实例 + * + * @param options 必须值 + * @param width 必须值 + * @param height 必须值 + * @param interfereCount 必须值 + * @param backgroundColor 必须值 + * @param transparency 必须值 + * @param fuzziness 必须值 + * @param fontName 可以空 + * @param fontStyle 必须值 + * @param fontSize 必须值 + * @param generator 必须值 + * @param length 必须值 + * @return 实例 + */ + public static DrawingOptions of(DrawingOptions options, int width, int height, int interfereCount, + ColorType backgroundColor, Float transparency, Integer fuzziness, Boolean validIgnoreCase, + String fontName, FontStyle fontStyle, Integer fontSize, + CodeGeneratorType generator, int length) { + FontOptions font = FontOptions.of(new FontOptions(), fontName, fontStyle, fontSize); + CodeOptions code = CodeOptions.of(new CodeOptions(), generator, length); + + options.setWidth(width); + options.setHeight(height); + options.setInterfereCount(interfereCount); + options.setBackgroundColor(backgroundColor); + options.setTransparency(transparency); + options.setFuzziness(fuzziness); + options.setValidIgnoreCase(validIgnoreCase); + + options.setFont(font); + options.setCode(code); + return options; + } + } + + /** + * 字体选项 + */ + @Data + public static class FontOptions { + /** + * 字体名称, 为空表示使用系统默认字体 + */ + private String name; + + /** + * 字体风格 + */ + private FontStyle style; + + /** + * 字体大小 + */ + private Integer size; + + /** + * 创建实例 + * + * @param options 必须值 + * @param name 可以空 + * @param style 必须值 + * @param size 必须值 + * @return 实例 + */ + public static FontOptions of(FontOptions options, String name, FontStyle style, Integer size) { + options.setName(name); + options.setStyle(style); + options.setSize(size); + return options; + } + + } + + /** + * 码选项 + */ + @Data + public static class CodeOptions { + /** + * 码生成类型 + */ + private CodeGeneratorType generator; + + /** + * 字符长度 + */ + private Integer length; + + /** + * 创建实例 + * + * @param options 必须值 + * @param generator 必须值 + * @param length 必须值 + * @return 实例 + */ + public static CodeOptions of(CodeOptions options, CodeGeneratorType generator, int length) { + options.setGenerator(generator); + options.setLength(length); + return options; + } + } +} diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/condition/EnumPropertyCondition.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/condition/EnumPropertyCondition.java similarity index 98% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/condition/EnumPropertyCondition.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/condition/EnumPropertyCondition.java index 4458c84ed79d0aab35f7d92fa07c5b5d7d63c4d7..cabe14f531cb31c5f0ddfc0f30903efbe6e74a09 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/condition/EnumPropertyCondition.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/condition/EnumPropertyCondition.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.condition; +package yunjiao.springboot.autoconfigure.condition; import lombok.extern.slf4j.Slf4j; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/hutool/SnowflakeAutoConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/id/HutoolIdConfiguration.java similarity index 65% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/hutool/SnowflakeAutoConfiguration.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/id/HutoolIdConfiguration.java index 8c4cea21508b6eb07472f420ef76f08a609baddc..467b0b73641ff22dbf42f4ba4ab875b12f059579 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/hutool/SnowflakeAutoConfiguration.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/id/HutoolIdConfiguration.java @@ -1,12 +1,10 @@ -package io.yunjiao.springboot.autoconfigure.hutool; +package yunjiao.springboot.autoconfigure.id; import cn.hutool.core.lang.Snowflake; import cn.hutool.core.util.IdUtil; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -18,14 +16,13 @@ import org.springframework.core.env.Environment; */ @Slf4j @Configuration(proxyBeanMethods = false) -@ConditionalOnClass({Snowflake.class}) -public class SnowflakeAutoConfiguration { +public class HutoolIdConfiguration { /** * {@link PostConstruct} 注解方法 */ @PostConstruct public void postConstruct() { - log.info("Hutool Snowflake Auto Configuration"); + log.info("Hutool Id Auto Configuration"); } /** @@ -36,20 +33,11 @@ public class SnowflakeAutoConfiguration { * @return 实例 */ @Bean - @ConditionalOnProperty( - prefix = PropertyNameConsts.PROPERTY_PREFIX_HUTOOL, - name = "snowflake", - havingValue = "true", - matchIfMissing = true - ) + @ConditionalOnClass({Snowflake.class}) public Snowflake snowflake(Environment env) { final String SNOWFLAKE_WORKER_ID = "SNOWFLAKE_WORKER_ID"; final String SNOWFLAKE_DATACENTER_ID = "SNOWFLAKE_DATACENTER_ID"; - if (log.isDebugEnabled()) { - log.debug("正在配置雪花算法,默认workerId=1,datacenterId=2。如需支持分布式,请设置系统环境变量:{} 与 {}", SNOWFLAKE_WORKER_ID, SNOWFLAKE_DATACENTER_ID); - } - long workerId = 1L; try { String workIdEnv = env.getProperty(SNOWFLAKE_WORKER_ID); @@ -68,7 +56,11 @@ public class SnowflakeAutoConfiguration { Snowflake snowflake = IdUtil.getSnowflake(workerId, datacenterId); if (log.isDebugEnabled()) { - log.debug("Configure Bean [Snowflake], workerId={}, datacenterId={}", workerId, datacenterId); + log.debug("Configure Bean [Snowflake: {}], workerId={}, datacenterId={}", snowflake, workerId, datacenterId); + } + + if (workerId == 1L && datacenterId == 1L) { + log.info("雪花算法配置参数workerId=1,datacenterId=1。如需支持分布式,请设置系统环境变量:{} 与 {}", SNOWFLAKE_WORKER_ID, SNOWFLAKE_DATACENTER_ID); } return snowflake; } diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/hutool/HutoolAutoConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/id/IdAutoConfiguration.java similarity index 51% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/hutool/HutoolAutoConfiguration.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/id/IdAutoConfiguration.java index b906dfe2026c33fdfb6f301a8e625f8daf4bd5e7..abaf5455085ac0b8d0fa7cac927a5b8225e83380 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/hutool/HutoolAutoConfiguration.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/id/IdAutoConfiguration.java @@ -1,33 +1,29 @@ -package io.yunjiao.springboot.autoconfigure.hutool; +package yunjiao.springboot.autoconfigure.id; -import cn.hutool.core.lang.Snowflake; +import yunjiao.springboot.extension.id._Id; import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Import; /** - * 基于Hutool框架的自动配置 + * 验证码 自动配置 * * @author yangyunjiao */ @Slf4j @AutoConfiguration -@ConditionalOnClass({Snowflake.class}) -@EnableConfigurationProperties({HutoolProperties.class}) +@ConditionalOnClass({_Id.class}) @Import({ - SnowflakeAutoConfiguration.class + HutoolIdConfiguration.class }) -public class HutoolAutoConfiguration { - +public class IdAutoConfiguration { /** * {@link PostConstruct} 注解方法 */ @PostConstruct public void postConstruct() { - log.info("Hutool Auto Configuration"); + log.info("Id Auto Configuration"); } - } diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/QueryDSLAutoConfig.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/QueryDSLAutoConfig.java similarity index 71% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/QueryDSLAutoConfig.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/QueryDSLAutoConfig.java index 3971b65fd844ec3e69c87badf1f1c755395ac5a0..f187620b6464fdc33fd332ddd5a0466dfc5d359e 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/QueryDSLAutoConfig.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/QueryDSLAutoConfig.java @@ -1,8 +1,8 @@ -package io.yunjiao.springboot.autoconfigure.querydsl; +package yunjiao.springboot.autoconfigure.querydsl; -import com.querydsl.core.QueryFactory; -import io.yunjiao.springboot.autoconfigure.querydsl.jpa.QuerydslJPAAutoConfiguration; -import io.yunjiao.springboot.autoconfigure.querydsl.sql.QuerydslSQLAutoConfiguration; +import yunjiao.springboot.extension.querydsl._Querydsl; +import yunjiao.springboot.autoconfigure.querydsl.jpa.QuerydslJPAAutoConfiguration; +import yunjiao.springboot.autoconfigure.querydsl.sql.QuerydslSQLAutoConfiguration; import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -17,7 +17,7 @@ import org.springframework.context.annotation.Import; */ @Slf4j @AutoConfiguration(after = DataSourceAutoConfiguration.class) -@ConditionalOnClass({QueryFactory.class}) +@ConditionalOnClass({_Querydsl.class}) @Import({ QuerydslJPAAutoConfiguration.class, QuerydslSQLAutoConfiguration.class diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/jpa/JPAQueryFactoryConfigurer.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/jpa/JPAQueryFactoryConfigurer.java similarity index 83% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/jpa/JPAQueryFactoryConfigurer.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/jpa/JPAQueryFactoryConfigurer.java index d5107f14bb0bb9bc5a973b620ba6dea2186c59f1..ffb3f9924fd777ae321f472d9431c0fb00c861ca 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/jpa/JPAQueryFactoryConfigurer.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/jpa/JPAQueryFactoryConfigurer.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.querydsl.jpa; +package yunjiao.springboot.autoconfigure.querydsl.jpa; import com.querydsl.jpa.impl.JPAQueryFactory; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/jpa/QuerydslJPAAutoConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/jpa/QuerydslJPAAutoConfiguration.java similarity index 93% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/jpa/QuerydslJPAAutoConfiguration.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/jpa/QuerydslJPAAutoConfiguration.java index 2052dd5b164f45b4f1e5a1e0cc660eca870ceecc..df1294ad933a0ece17ae4d3e908075febf61fd47 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/jpa/QuerydslJPAAutoConfiguration.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/jpa/QuerydslJPAAutoConfiguration.java @@ -1,7 +1,7 @@ -package io.yunjiao.springboot.autoconfigure.querydsl.jpa; +package yunjiao.springboot.autoconfigure.querydsl.jpa; import com.querydsl.jpa.impl.JPAQueryFactory; -import io.yunjiao.extension.querydsl.jpa.JPAQueryCurdExecutor; +import yunjiao.springboot.extension.querydsl.jpa.JPAQueryCurdExecutor; import jakarta.annotation.PostConstruct; import jakarta.persistence.EntityManager; import lombok.RequiredArgsConstructor; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/sql/QuerydslSQLAutoConfiguration.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/sql/QuerydslSQLAutoConfiguration.java similarity index 95% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/sql/QuerydslSQLAutoConfiguration.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/sql/QuerydslSQLAutoConfiguration.java index f65e35c17bc31f12e32cf8ec32b991e7fdf69c93..d7442ecaf16ce83f119d98695cbc60eb13e8f7a1 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/sql/QuerydslSQLAutoConfiguration.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/sql/QuerydslSQLAutoConfiguration.java @@ -1,11 +1,11 @@ -package io.yunjiao.springboot.autoconfigure.querydsl.sql; +package yunjiao.springboot.autoconfigure.querydsl.sql; import com.querydsl.sql.MySQLTemplates; import com.querydsl.sql.SQLQueryFactory; import com.querydsl.sql.SQLTemplates; import com.querydsl.sql.spring.SpringConnectionProvider; import com.querydsl.sql.spring.SpringExceptionTranslator; -import io.yunjiao.extension.querydsl.sql.SQLQueryCurdExecutor; +import yunjiao.springboot.extension.querydsl.sql.SQLQueryCurdExecutor; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/sql/SQLQueryFactoryConfigurer.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/sql/SQLQueryFactoryConfigurer.java similarity index 83% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/sql/SQLQueryFactoryConfigurer.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/sql/SQLQueryFactoryConfigurer.java index 38b630146061df7f113949d53f8f968b994512b6..18a1ded77a271cac318d82c84c244a4bd67ab15f 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/querydsl/sql/SQLQueryFactoryConfigurer.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/querydsl/sql/SQLQueryFactoryConfigurer.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.querydsl.sql; +package yunjiao.springboot.autoconfigure.querydsl.sql; import com.querydsl.sql.SQLQueryFactory; diff --git a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/util/PropertyNameConsts.java b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/util/PropertyNameConsts.java similarity index 60% rename from autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/util/PropertyNameConsts.java rename to autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/util/PropertyNameConsts.java index 9fa85f83671100276f1a4d266ae7398cd68bac90..bbe600018dbbdca8d6d4c74a913fb0029f7e68f1 100644 --- a/autoconfigure/src/main/java/io/yunjiao/springboot/autoconfigure/util/PropertyNameConsts.java +++ b/autoconfigure/src/main/java/yunjiao/springboot/autoconfigure/util/PropertyNameConsts.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.util; +package yunjiao.springboot.autoconfigure.util; /** * 属性名称常量定义 @@ -17,9 +17,19 @@ public class PropertyNameConsts { public static final String PROPERTY_PREFIX_SPRING = "spring"; /** - * hutool 属性 + * 验证码属性 */ - public static final String PROPERTY_PREFIX_HUTOOL = PROPERTY_PREFIX_SPRING + ".hutool"; + public static final String PROPERTY_PREFIX_CAPTCHA = PROPERTY_PREFIX_SPRING + ".captcha"; + + /** + * 验证码属性 Hutool + */ + public static final String PROPERTY_PREFIX_CAPTCHA_HUTOOL = PROPERTY_PREFIX_CAPTCHA + ".hutool"; + + /** + * 验证码属性 Hutool + */ + public static final String PROPERTY_PREFIX_CAPTCHA_ANJI = PROPERTY_PREFIX_CAPTCHA + ".anji"; // APIJSON @@ -29,37 +39,37 @@ public class PropertyNameConsts { public static final String PROPERTY_PREFIX_APIJSON = PROPERTY_PREFIX_SPRING + ".apijson"; /** - * rest-api 属性 + * apijson rest-api 属性 */ public static final String PROPERTY_PREFIX_APIJSON_RESTAPI = PROPERTY_PREFIX_APIJSON + ".rest-api"; /** - * enabled 属性 + * apijson rest-api enabled 属性 */ - public static final String PROPERTY_PREFIX_APIJSON_RESTAPI_ENABLE = PROPERTY_PREFIX_APIJSON_RESTAPI + PROPERTY_ENABLED; + public static final String PROPERTY_APIJSON_RESTAPI_ENABLE = PROPERTY_PREFIX_APIJSON_RESTAPI + PROPERTY_ENABLED; /** - * sql 属性 + * apijson sql 属性 */ public static final String PROPERTY_PREFIX_APIJSON_SQL = PROPERTY_PREFIX_APIJSON + ".sql"; /** - * parser 属性 + * apijson parser 属性 */ public static final String PROPERTY_PREFIX_APIJSON_PARSER = PROPERTY_PREFIX_APIJSON + ".parser"; /** - * verifier 属性 + * apijson verifier 属性 */ public static final String PROPERTY_PREFIX_APIJSON_VERIFIER = PROPERTY_PREFIX_APIJSON + ".verifier"; /** - * application 属性 + * apijson application 属性 */ public static final String PROPERTY_PREFIX_APIJSON_APPLICATION = PROPERTY_PREFIX_APIJSON + ".application"; /** - * newidstrategy 属性 + * apijson newidstrategy 属性 */ public static final String PROPERTY_PREFIX_APIJSON_NEWIDSTRATEGY = PROPERTY_PREFIX_APIJSON + ".new-id-strategy"; diff --git a/autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 74c3af459530347f013bdbf38e61d1d49ed3e474..f693d01c5a51714b3e987f989b69bb224013e525 100644 --- a/autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,3 +1,4 @@ -io.yunjiao.springboot.autoconfigure.querydsl.QueryDSLAutoConfig -io.yunjiao.springboot.autoconfigure.hutool.HutoolAutoConfiguration -io.yunjiao.springboot.autoconfigure.apijson.ApijsonAutoConfiguration \ No newline at end of file +yunjiao.springboot.autoconfigure.querydsl.QueryDSLAutoConfig +yunjiao.springboot.autoconfigure.id.IdAutoConfiguration +yunjiao.springboot.autoconfigure.captcha.CaptchaAutoConfiguration +yunjiao.springboot.autoconfigure.apijson.ApijsonAutoConfiguration \ No newline at end of file diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfigurationTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfigurationTest.java similarity index 57% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfigurationTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfigurationTest.java index d0e750ca2c0c165228981d720c6231fa631bca06..c118988073ec6e911f252a595b4081202ee69b98 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfigurationTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonAutoConfigurationTest.java @@ -1,20 +1,18 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; -import io.yunjiao.extension.apjson.orm.IdKeyApijsonStrategy; -import io.yunjiao.extension.apjson.orm.IdKeyStrategy; +import yunjiao.springboot.extension.apjson.orm.IdKeyApijsonStrategy; +import yunjiao.springboot.extension.apjson.orm.IdKeyStrategy; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -import javax.sql.DataSource; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertInstanceOf; /** - * {@link NewIdStrategyAutoConfiguration}单元测试用例 + * {@link NewIdStrategyConfiguration}单元测试用例 * * @author yangyunjiao */ @@ -28,13 +26,18 @@ public class ApijsonAutoConfigurationTest { } @Test - public void testNewIdSnowflakeStrategy() { + public void shouldAutoConfigurationApplied() { applicationContextRunner - .withBean(DataSource.class, () -> Mockito.mock(DataSource.class)) .run(context -> { assertThat(context).hasSingleBean(IdKeyStrategy.class); IdKeyStrategy strategy = context.getBean(IdKeyStrategy.class); assertInstanceOf(IdKeyApijsonStrategy.class, strategy); + + assertThat(context).hasSingleBean(WebMvcConfigurer.class); + assertThat(context).hasSingleBean(ApijsonProperties.class); + assertThat(context).hasSingleBean(ApijsonSqlProperties.class); + assertThat(context).hasSingleBean(ApijsonParserProperties.class); + assertThat(context).hasSingleBean(ApijsonVerifierProperties.class); }); } diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurerTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurerTest.java similarity index 60% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurerTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurerTest.java index afe97cbd55e29dc80088a1904f8df6d373c68f75..0736b33738cadb11488f0c8053d85dd66149849d 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurerTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonFunctionParserConfigurerTest.java @@ -1,5 +1,6 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; +import apijson.framework.APIJSONFunctionParser; import apijson.orm.AbstractFunctionParser; import apijson.orm.script.ScriptExecutor; import org.junit.jupiter.api.Test; @@ -17,10 +18,18 @@ import static org.assertj.core.api.Assertions.assertThat; public class ApijsonFunctionParserConfigurerTest { @Test - void testDefault() { + void givenImplement_whenBuild_thenCheckStaticOk() { ApijsonFunctionParserConfigurer configurer = new ApijsonFunctionParserConfigurerDemo(); - ApijsonUtils.buildAPIJSONFunctionParserStatic(new ApijsonParserProperties.Function(), List.of(configurer)); - + ApijsonParserProperties.Function function = new ApijsonParserProperties.Function(); + function.setParseArgValue(true); + function.setEnableRemoteFunction(false); + function.setEnableScriptFunction(false); + ApijsonUtils.forceInit(APIJSONFunctionParser.class); + ApijsonUtils.buildAPIJSONFunctionParserStatic(function, List.of(configurer)); + + assertThat(APIJSONFunctionParser.ENABLE_REMOTE_FUNCTION).isEqualTo(function.isEnableRemoteFunction()); + assertThat(APIJSONFunctionParser.ENABLE_SCRIPT_FUNCTION).isEqualTo(function.isEnableScriptFunction()); + assertThat(APIJSONFunctionParser.IS_PARSE_ARG_VALUE).isEqualTo(function.isParseArgValue()); assertThat(AbstractFunctionParser.SCRIPT_EXECUTOR_MAP).hasSize(1); assertThat(AbstractFunctionParser.SCRIPT_EXECUTOR_MAP).containsKey("scriptExecutorMap"); assertThat(AbstractFunctionParser.FUNCTION_MAP).hasSize(1); diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonInitAutoConfigurationTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonInitConfigurationTest.java similarity index 89% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonInitAutoConfigurationTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonInitConfigurationTest.java index fbb36c66828e1220a2c3b96e3dc068123d1ac36b..8ca7d33dbc5a852fc4981eb437ce66607da0c5e6 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonInitAutoConfigurationTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonInitConfigurationTest.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -12,21 +12,21 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; /** - * {@link ApijsonInitAutoConfiguration} 单元测试用例 + * {@link ApijsonInitConfiguration} 单元测试用例 * * @author yangyunjiao */ -public class ApijsonInitAutoConfigurationTest { +public class ApijsonInitConfigurationTest { private ApplicationContextRunner applicationContextRunner; @BeforeEach public void setUp() { applicationContextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ApijsonInitAutoConfiguration.class, TestConfiguration.class)); + .withConfiguration(AutoConfigurations.of(ApijsonInitConfiguration.class, TestConfiguration.class)); } @Test - public void testDefault() { + public void givenNoConfigurer_whenConfig() { applicationContextRunner.run(context -> { assertThat(context).doesNotHaveBean(ApijsonSqlConfigConfigurer.class); assertThat(context).doesNotHaveBean(ApijsonVerifierConfigurer.class); @@ -36,7 +36,7 @@ public class ApijsonInitAutoConfigurationTest { } @Test - public void testWithConfigurer() { + public void givenConfigurer_whenConfig() { applicationContextRunner .withUserConfiguration(ConfigurerConfiguration.class) .run(context -> { diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonPropertiesTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonPropertiesTest.java similarity index 89% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonPropertiesTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonPropertiesTest.java index da3265ebfde5dfd097fc6db7cbc87cac785d164e..e6a874692d2acbb14a0241fef82f901c76419020 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonPropertiesTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonPropertiesTest.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -19,7 +19,7 @@ public class ApijsonPropertiesTest { private ApijsonProperties properties; @Test - public void defaultValue() { + public void givenProperties_thenCheckDefaultOk() { assertThat(properties.getApplication()).isEqualTo(ApijsonProperties.Application.fastjson2); assertThat(properties.getNewIdStrategy()).isEqualTo(ApijsonProperties.NewIdStrategy.timestamp); } diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurerTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurerTest.java similarity index 58% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurerTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurerTest.java index 72fb93a93b5a7597df0c636c717922dc8a5cc8af..6cc802ba4da288ae81ba16c47c81ae7112c98679 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurerTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlConfigConfigurerTest.java @@ -1,5 +1,6 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; +import apijson.framework.APIJSONSQLConfig; import apijson.framework.ColumnUtil; import apijson.orm.AbstractSQLConfig; import org.junit.jupiter.api.Test; @@ -19,7 +20,21 @@ public class ApijsonSqlConfigConfigurerTest { @Test void testDefault() { ApijsonSqlConfigConfigurer configurer = new ApijsonSqlConfigConfigurerDemo(); - ApijsonUtils.buildAPIJSONSQLConfigStatic(new ApijsonSqlProperties.Config(), List.of(configurer)); + ApijsonSqlProperties.Config config = new ApijsonSqlProperties.Config(); + config.setEnableColumnConfig(false); + config.setDefaultDatabase("database"); + config.setDefaultCatalog("catalog"); + config.setDefaultSchema("schema"); + config.setDefaultNamespace("namespace"); + config.setVersion("version"); + ApijsonUtils.forceInit(APIJSONSQLConfig.class); + ApijsonUtils.buildAPIJSONSQLConfigStatic(config, List.of(configurer)); + + assertThat(APIJSONSQLConfig.DEFAULT_DATABASE).isEqualTo(config.getDefaultDatabase()); + assertThat(APIJSONSQLConfig.DEFAULT_SCHEMA).isEqualTo(config.getDefaultSchema()); + assertThat(APIJSONSQLConfig.DEFAULT_CATALOG).isEqualTo(config.getDefaultCatalog()); + assertThat(APIJSONSQLConfig.DEFAULT_NAMESPACE).isEqualTo(config.getDefaultNamespace()); + assertThat(APIJSONSQLConfig.ENABLE_COLUMN_CONFIG).isEqualTo(config.isEnableColumnConfig()); assertThat(AbstractSQLConfig.RAW_MAP).containsEntry("rawMap", "rawMap1"); assertThat(ColumnUtil.VERSIONED_TABLE_COLUMN_MAP).hasSize(1); diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlPropertiesTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlPropertiesTest.java similarity index 83% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlPropertiesTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlPropertiesTest.java index 957626ce338137aa077c7a8c8cd07300e28f8288..7b492d80264aacabd699c113c04d6d2b0d6c19ac 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlPropertiesTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonSqlPropertiesTest.java @@ -1,6 +1,6 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; -import io.yunjiao.extension.apjson.util.ApijsonConsts; +import yunjiao.springboot.extension.apjson.util.ApijsonConsts; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; @@ -20,7 +20,7 @@ public class ApijsonSqlPropertiesTest { private ApijsonSqlProperties properties; @Test - public void configDefaultValue() { + public void givenProperties_whenGetConfig_thenCheckDefaultOk() { ApijsonSqlProperties.Config confg = properties.getConfig(); assertThat(confg.getDefaultDatabase()).isEqualTo(ApijsonConsts.SQL_CONFIG_DEFAULT_DATABASE); assertThat(confg.getDefaultSchema()).isEqualTo(ApijsonConsts.SQL_CONFIG_DEFAULT_SCHEMA); @@ -28,7 +28,7 @@ public class ApijsonSqlPropertiesTest { } @Test - public void excutorDefaultValue() { + public void givenProperties_whenGetExecutor_thenCheckDefaultOk() { ApijsonSqlProperties.Executor executor = properties.getExecutor(); assertThat(executor.getKeyRawList()).isEqualTo(ApijsonConsts.SQL_EXECUTOR_KEY_RAW_LIST); assertThat(executor.getKeyViceItem()).isEqualTo(ApijsonConsts.SQL_EXECUTOR_KEY_VICE_ITEM); diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonUtilsTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonUtilsTest.java similarity index 96% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonUtilsTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonUtilsTest.java index b049f3cf5e1491a3e6dfd2a077fb4ceb845627d8..ab1065546acfb597b85fe26c635ec3842d58519b 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonUtilsTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonUtilsTest.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import apijson.StringUtil; import org.junit.jupiter.api.Test; diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurerTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurerTest.java similarity index 63% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurerTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurerTest.java index 69b08965443ffd92ce0471bcaae60f72204cdc90..4e41c58ca9997368f8e4580a95636c8113b0723a 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurerTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/ApijsonVerifierConfigurerTest.java @@ -1,6 +1,7 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import apijson.RequestMethod; +import apijson.framework.APIJSONVerifier; import apijson.orm.AbstractVerifier; import apijson.orm.Entry; import org.junit.jupiter.api.Test; @@ -20,9 +21,23 @@ import static org.assertj.core.api.Assertions.assertThat; public class ApijsonVerifierConfigurerTest { @Test - void testDefault() { + void givenImplement_whenBuild_thenCheckStaticOk() { ApijsonVerifierConfigurerDemo configurer = new ApijsonVerifierConfigurerDemo(); - ApijsonUtils.buildAPIJSONVerifierStatic(new ApijsonVerifierProperties(), List.of(configurer)); + ApijsonVerifierProperties properties = new ApijsonVerifierProperties(); + properties.setEnableVerifyColumn(false); + properties.setEnableApijsonRouter(true); + properties.setUpdateMustHaveIdCondition(false); + properties.setEnableVerifyRole(false); + properties.setEnableVerifyContent(false); + + ApijsonUtils.forceInit(AbstractVerifier.class, APIJSONVerifier.class); + ApijsonUtils.buildAPIJSONVerifierStatic(properties, List.of(configurer)); + + assertThat(APIJSONVerifier.ENABLE_APIJSON_ROUTER).isEqualTo(properties.isEnableApijsonRouter()); + assertThat(APIJSONVerifier.ENABLE_VERIFY_COLUMN).isEqualTo(properties.isEnableVerifyColumn()); + assertThat(AbstractVerifier.IS_UPDATE_MUST_HAVE_ID_CONDITION).isEqualTo(properties.isUpdateMustHaveIdCondition()); + assertThat(AbstractVerifier.ENABLE_VERIFY_ROLE).isEqualTo(properties.isEnableVerifyRole()); + assertThat(AbstractVerifier.ENABLE_VERIFY_CONTENT).isEqualTo(properties.isEnableVerifyContent()); assertThat(AbstractVerifier.ROLE_MAP).containsKey("roleMap"); assertThat(AbstractVerifier.OPERATION_KEY_LIST).contains("operationKeyList"); diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyAutoConfigurationTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyConfigurationTest.java similarity index 82% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyAutoConfigurationTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyConfigurationTest.java index 0fb0521dcee552df5f4371b1d82b62afaa61a26f..6bb1bcf0a8e56ab034123fc86be543023981b669 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyAutoConfigurationTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/NewIdStrategyConfigurationTest.java @@ -1,34 +1,34 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; import cn.hutool.core.lang.Snowflake; -import io.yunjiao.extension.apjson.orm.*; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import yunjiao.springboot.extension.apjson.orm.*; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertTrue; /** - * {@link NewIdStrategyAutoConfiguration}单元测试用例 + * {@link NewIdStrategyConfiguration}单元测试用例 * * @author yangyunjiao */ -public class NewIdStrategyAutoConfigurationTest { +public class NewIdStrategyConfigurationTest { private ApplicationContextRunner applicationContextRunner; @BeforeEach public void setUp() { applicationContextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(NewIdStrategyAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(NewIdStrategyConfiguration.class)); } @Test - public void testNewIdSnowflakeStrategy() { + public void givenPropertySnowflake_whenConfig() { applicationContextRunner .withPropertyValues(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_NEWIDSTRATEGY + "=" + ApijsonProperties.NewIdStrategy.snowflake) .withBean(Snowflake.class, () -> Mockito.mock(Snowflake.class)) @@ -40,7 +40,7 @@ public class NewIdStrategyAutoConfigurationTest { } @Test - public void testNewIdTimestampStrategy() { + public void givenPropertyTimestamp_whenConfig() { applicationContextRunner .withPropertyValues(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_NEWIDSTRATEGY + "=" + ApijsonProperties.NewIdStrategy.timestamp) .run(context -> { @@ -51,7 +51,7 @@ public class NewIdStrategyAutoConfigurationTest { } @Test - public void testNewIdUuidStrategy() { + public void givenPropertyUuid_whenConfig() { applicationContextRunner .withPropertyValues(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_NEWIDSTRATEGY + "=" + ApijsonProperties.NewIdStrategy.uuid) .run(context -> { @@ -62,13 +62,13 @@ public class NewIdStrategyAutoConfigurationTest { } @Test - public void testNewIdCustomStrategy() { + public void givenPropertyCustom_whenConfig() { applicationContextRunner .withPropertyValues(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_NEWIDSTRATEGY + "=" + ApijsonProperties.NewIdStrategy.custom) .run(context -> { assertThat(context).hasSingleBean(NewIdStrategy.class); NewIdStrategy strategy = context.getBean(NewIdStrategy.class); - assertTrue(strategy instanceof NewIdExceptionStrategy); + assertInstanceOf(NewIdExceptionStrategy.class, strategy); }); } diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/RestApiAutoConfigurationTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/RestApiAutoConfigurationTest.java similarity index 61% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/RestApiAutoConfigurationTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/RestApiAutoConfigurationTest.java index 8dd288247c9fcdf48d98e256588c3185fc6b7e06..b630572587482edfc107f6370be2f6960740115b 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/RestApiAutoConfigurationTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/RestApiAutoConfigurationTest.java @@ -1,10 +1,10 @@ -package io.yunjiao.springboot.autoconfigure.apijson; +package yunjiao.springboot.autoconfigure.apijson; -import io.yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2EXtRestController; -import io.yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2RestController; -import io.yunjiao.springboot.autoconfigure.apijson.gson.GsonEXtRestController; -import io.yunjiao.springboot.autoconfigure.apijson.gson.GsonRestController; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2EXtRestController; +import yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2RestController; +import yunjiao.springboot.autoconfigure.apijson.gson.GsonEXtRestController; +import yunjiao.springboot.autoconfigure.apijson.gson.GsonRestController; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -27,10 +27,10 @@ public class RestApiAutoConfigurationTest { } @Test - public void fastjson2RestApiEnabled() { + public void givenPropertyRestApiEnable_whenTrue_thenFastjson2Config() { applicationContextRunner - .withPropertyValues(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_RESTAPI_ENABLE + "=true") - .withUserConfiguration(Fastjson2ApplicationAutoConfiguration.Fastjson2RestApiAutoConfiguration.class) + .withPropertyValues(PropertyNameConsts.PROPERTY_APIJSON_RESTAPI_ENABLE + "=true") + .withUserConfiguration(Fastjson2ApplicationConfiguration.Fastjson2RestApiAutoConfiguration.class) .run(context -> { assertThat(context).hasSingleBean(Fastjson2RestController.class); assertThat(context).hasSingleBean(Fastjson2EXtRestController.class); @@ -38,10 +38,10 @@ public class RestApiAutoConfigurationTest { } @Test - public void fastjson2RestApiDisabled() { + public void givenPropertyRestApiEnable_whenFalse_thenFastjson2Config() { applicationContextRunner - .withPropertyValues(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_RESTAPI_ENABLE + "=false") - .withUserConfiguration(Fastjson2ApplicationAutoConfiguration.Fastjson2RestApiAutoConfiguration.class) + .withPropertyValues(PropertyNameConsts.PROPERTY_APIJSON_RESTAPI_ENABLE + "=false") + .withUserConfiguration(Fastjson2ApplicationConfiguration.Fastjson2RestApiAutoConfiguration.class) .run(context -> { assertThat(context).doesNotHaveBean(Fastjson2RestController.class); assertThat(context).doesNotHaveBean(Fastjson2EXtRestController.class); @@ -49,10 +49,10 @@ public class RestApiAutoConfigurationTest { } @Test - public void GsonRestApiEnabled() { + public void givenPropertyRestApiEnable_whenTrue_thenGsonConfig() { applicationContextRunner - .withPropertyValues(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_RESTAPI_ENABLE + "=true") - .withUserConfiguration(GsonApplicationAutoConfiguration.GsonRestApiAutoConfiguration.class) + .withPropertyValues(PropertyNameConsts.PROPERTY_APIJSON_RESTAPI_ENABLE + "=true") + .withUserConfiguration(GsonApplicationConfiguration.GsonRestApiAutoConfiguration.class) .run(context -> { assertThat(context).hasSingleBean(GsonRestController.class); assertThat(context).hasSingleBean(GsonEXtRestController.class); @@ -60,10 +60,10 @@ public class RestApiAutoConfigurationTest { } @Test - public void GsonRestApiDisabled() { + public void givenPropertyRestApiEnable_whenFalse_thenGsonConfig() { applicationContextRunner - .withPropertyValues(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_RESTAPI_ENABLE + "=false") - .withUserConfiguration(GsonApplicationAutoConfiguration.GsonRestApiAutoConfiguration.class) + .withPropertyValues(PropertyNameConsts.PROPERTY_APIJSON_RESTAPI_ENABLE + "=false") + .withUserConfiguration(GsonApplicationConfiguration.GsonRestApiAutoConfiguration.class) .run(context -> { assertThat(context).doesNotHaveBean(GsonRestController.class); assertThat(context).doesNotHaveBean(GsonEXtRestController.class); diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationConditionTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationConditionTest.java similarity index 85% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationConditionTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationConditionTest.java index 346ffbd1387493a6c04ea5ec8202f2b69e73f74c..4e5c4daec5231feb6ee91a53b6a8188500c60549 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationConditionTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/condition/ApllicationConditionTest.java @@ -1,7 +1,7 @@ -package io.yunjiao.springboot.autoconfigure.apijson.condition; +package yunjiao.springboot.autoconfigure.apijson.condition; -import io.yunjiao.springboot.autoconfigure.test.TestUtils; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.autoconfigure.test.TestUtils; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -24,7 +24,7 @@ public class ApllicationConditionTest { private AnnotatedTypeMetadata metadata; @Test - void shouldMatchWhenPropertyMatchesExpectedType_Gson() { + void shouldMatchWhenPropertyMatchesGson() { MockEnvironment env = new MockEnvironment(); env.setProperty(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_APPLICATION, "gson"); @@ -38,7 +38,7 @@ public class ApllicationConditionTest { } @Test - void shouldMatchWhenPropertyMatchesExpectedType_Fastjson2() { + void shouldMatchWhenPropertyMatchesFastjson2() { MockEnvironment env = new MockEnvironment(); env.setProperty(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_APPLICATION, "fastjson2"); diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyConditionTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyConditionTest.java similarity index 87% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyConditionTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyConditionTest.java index fd81ec40e9d0f30b619f04e5eb2021b98b556575..df99d880c14c3bed51a0b15301ad229d44b30547 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyConditionTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/apijson/condition/NewIdStrategyConditionTest.java @@ -1,7 +1,7 @@ -package io.yunjiao.springboot.autoconfigure.apijson.condition; +package yunjiao.springboot.autoconfigure.apijson.condition; -import io.yunjiao.springboot.autoconfigure.test.TestUtils; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; +import yunjiao.springboot.autoconfigure.test.TestUtils; +import yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -24,7 +24,7 @@ public class NewIdStrategyConditionTest { private AnnotatedTypeMetadata metadata; @Test - void shouldMatchWhenPropertyMatchesExpectedType_Database() { + void shouldMatchWhenPropertyMatchesDatabase() { MockEnvironment env = new MockEnvironment(); env.setProperty(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_NEWIDSTRATEGY, "database"); @@ -38,7 +38,7 @@ public class NewIdStrategyConditionTest { } @Test - void shouldMatchWhenPropertyMatchesExpectedType_Snowflake() { + void shouldMatchWhenPropertyMatchesSnowflake() { MockEnvironment env = new MockEnvironment(); env.setProperty(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_NEWIDSTRATEGY, "snowflake"); @@ -52,7 +52,7 @@ public class NewIdStrategyConditionTest { } @Test - void shouldMatchWhenPropertyMatchesExpectedType_Timestamp() { + void shouldMatchWhenPropertyMatchesTimestamp() { MockEnvironment env = new MockEnvironment(); env.setProperty(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_NEWIDSTRATEGY, "timestamp"); @@ -66,7 +66,7 @@ public class NewIdStrategyConditionTest { } @Test - void shouldMatchWhenPropertyMatchesExpectedType_Uuid() { + void shouldMatchWhenPropertyMatchesUuid() { MockEnvironment env = new MockEnvironment(); env.setProperty(PropertyNameConsts.PROPERTY_PREFIX_APIJSON_NEWIDSTRATEGY, "uuid"); diff --git a/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/captcha/AnjiCaptchaConfigurationTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/captcha/AnjiCaptchaConfigurationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6445404508a9aafd98cdab206e9cd47dbbf5ae1d --- /dev/null +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/captcha/AnjiCaptchaConfigurationTest.java @@ -0,0 +1,40 @@ +package yunjiao.springboot.autoconfigure.captcha; + +import com.anji.captcha.service.CaptchaCacheService; +import com.anji.captcha.service.CaptchaService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import yunjiao.springboot.extension.captcha.anji.BlockPuzzleCaptchaService; +import yunjiao.springboot.extension.captcha.anji.ClickWorkCaptchaService; +import yunjiao.springboot.extension.captcha.anji.RotatePluzzleCaptchaService; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * {@link AnjiCaptchaConfiguration} 单元测试用例 + * + * @author yangyunjiao + */ +public class AnjiCaptchaConfigurationTest { + private ApplicationContextRunner applicationContextRunner; + + @BeforeEach + public void setUp() { + applicationContextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(AnjiCaptchaConfiguration.class)); + } + + @Test + public void givenDefault_thenConfig() { + applicationContextRunner + .run(context -> { + assertThat(context).hasSingleBean(CaptchaCacheService.class); + assertThat(context).hasSingleBean(CaptchaService.class); + assertThat(context).hasSingleBean(BlockPuzzleCaptchaService.class); + assertThat(context).hasSingleBean(ClickWorkCaptchaService.class); + assertThat(context).hasSingleBean(RotatePluzzleCaptchaService.class); + }); + } +} diff --git a/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/captcha/CaptchaAutoConfigurationTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/captcha/CaptchaAutoConfigurationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9d4a3b2351c002b1ee001f890412f9b7293191b9 --- /dev/null +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/captcha/CaptchaAutoConfigurationTest.java @@ -0,0 +1,34 @@ +package yunjiao.springboot.autoconfigure.captcha; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * {@link CaptchaAutoConfiguration} 单元测试用例 + * + * @author yangyunjiao + */ +public class CaptchaAutoConfigurationTest { + private ApplicationContextRunner applicationContextRunner; + + @BeforeEach + public void setUp() { + applicationContextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(CaptchaAutoConfiguration.class)); + } + + @Test + public void givenDefault_thenConfig() { + applicationContextRunner + .run(context -> { + assertThat(context).hasSingleBean(CaptchaServiceFactory.class); + + CaptchaServiceFactory factory = context.getBean(CaptchaServiceFactory.class); + assertThat(factory.services()).hasSize(7); + }); + } +} diff --git a/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/captcha/HutoolCaptchaConfigurationTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/captcha/HutoolCaptchaConfigurationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..580dd9bbd9f476ae3a760d0b04868080478f9871 --- /dev/null +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/captcha/HutoolCaptchaConfigurationTest.java @@ -0,0 +1,38 @@ +package yunjiao.springboot.autoconfigure.captcha; + +import yunjiao.springboot.extension.captcha.hutool.CircleCaptchaService; +import yunjiao.springboot.extension.captcha.hutool.GifCaptchaService; +import yunjiao.springboot.extension.captcha.hutool.LineCaptchaService; +import yunjiao.springboot.extension.captcha.hutool.ShearCaptchaService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * {@link HutoolCaptchaConfiguration} 单元测试用例 + * + * @author yangyunjiao + */ +public class HutoolCaptchaConfigurationTest { + private ApplicationContextRunner applicationContextRunner; + + @BeforeEach + public void setUp() { + applicationContextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(HutoolCaptchaConfiguration.class)); + } + + @Test + public void givenDefault_thenConfig() { + applicationContextRunner + .run(context -> { + assertThat(context).hasSingleBean(LineCaptchaService.class); + assertThat(context).hasSingleBean(CircleCaptchaService.class); + assertThat(context).hasSingleBean(ShearCaptchaService.class); + assertThat(context).hasSingleBean(GifCaptchaService.class); + }); + } +} diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/condition/EnumPropertyConditionTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/condition/EnumPropertyConditionTest.java similarity index 91% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/condition/EnumPropertyConditionTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/condition/EnumPropertyConditionTest.java index 7b67edcb0f4a19ff2bdc1835d9ba739c033d1a6d..7042d5b6c71fba0dc5d16f6a4bad4ccbddca0d28 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/condition/EnumPropertyConditionTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/condition/EnumPropertyConditionTest.java @@ -1,6 +1,6 @@ -package io.yunjiao.springboot.autoconfigure.condition; +package yunjiao.springboot.autoconfigure.condition; -import io.yunjiao.springboot.autoconfigure.test.TestUtils; +import yunjiao.springboot.autoconfigure.test.TestUtils; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -24,7 +24,7 @@ public class EnumPropertyConditionTest { private AnnotatedTypeMetadata metadata; @Test - void giveCorrectValue_thenMatched() { + void givenCorrectValue_thenMatched() { // 准备测试环境 MockEnvironment env = new MockEnvironment(); env.setProperty(PROPERTY_NAME, "female"); @@ -43,7 +43,7 @@ public class EnumPropertyConditionTest { } @Test - void giveWrongValue_thenNotMatched() { + void givenWrongValue_thenNotMatched() { // 准备测试环境 MockEnvironment env = new MockEnvironment(); env.setProperty(PROPERTY_NAME, "Female"); diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/hutool/SnowflakeAutoConfigurationTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/id/IdIdConfigurationTest.java similarity index 49% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/hutool/SnowflakeAutoConfigurationTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/id/IdIdConfigurationTest.java index 4250eb15a8cff50415c60a6c97ca7325b1664786..6393e700fadf7c5dffe39b43bd0270142a967ad6 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/hutool/SnowflakeAutoConfigurationTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/id/IdIdConfigurationTest.java @@ -1,8 +1,6 @@ -package io.yunjiao.springboot.autoconfigure.hutool; +package yunjiao.springboot.autoconfigure.id; import cn.hutool.core.lang.Snowflake; -import io.yunjiao.springboot.autoconfigure.hutool.SnowflakeAutoConfiguration; -import io.yunjiao.springboot.autoconfigure.util.PropertyNameConsts; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -11,30 +9,21 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; /** - * {@link SnowflakeAutoConfiguration} 单元测试用例 + * {@link HutoolIdConfiguration} 单元测试用例 * * @author yangyunjiao */ -public class SnowflakeAutoConfigurationTest { +public class IdIdConfigurationTest { private ApplicationContextRunner applicationContextRunner; @BeforeEach public void setUp() { applicationContextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(SnowflakeAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(HutoolIdConfiguration.class)); } @Test - public void testDisable() { - applicationContextRunner - .withPropertyValues(PropertyNameConsts.PROPERTY_PREFIX_HUTOOL + ".snowflake=false") - .run(context -> { - assertThat(context).doesNotHaveBean(Snowflake.class); - }); - } - - @Test - public void testEnable() { + public void givenDefault_thenConfig() { applicationContextRunner .run(context -> { assertThat(context).hasSingleBean(Snowflake.class); diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/querydsl/QuerydslJPAAutoConfigurationTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/querydsl/QuerydslJPAAutoConfigurationTest.java similarity index 76% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/querydsl/QuerydslJPAAutoConfigurationTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/querydsl/QuerydslJPAAutoConfigurationTest.java index 9d13784660cb73d4b8468208c152d271ffa90880..94d4dc94aa49356c7fa6859baa6729d6394dd5fd 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/querydsl/QuerydslJPAAutoConfigurationTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/querydsl/QuerydslJPAAutoConfigurationTest.java @@ -1,9 +1,9 @@ -package io.yunjiao.springboot.autoconfigure.querydsl; +package yunjiao.springboot.autoconfigure.querydsl; import com.querydsl.jpa.impl.JPAQueryFactory; -import io.yunjiao.extension.querydsl.jpa.JPAQueryCurdExecutor; -import io.yunjiao.springboot.autoconfigure.querydsl.jpa.JPAQueryFactoryConfigurer; -import io.yunjiao.springboot.autoconfigure.querydsl.jpa.QuerydslJPAAutoConfiguration; +import yunjiao.springboot.extension.querydsl.jpa.JPAQueryCurdExecutor; +import yunjiao.springboot.autoconfigure.querydsl.jpa.JPAQueryFactoryConfigurer; +import yunjiao.springboot.autoconfigure.querydsl.jpa.QuerydslJPAAutoConfiguration; import jakarta.persistence.EntityManager; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -31,10 +31,10 @@ public class QuerydslJPAAutoConfigurationTest { } @Test - public void giveEntityManager_thenExist() { + public void givenEntityManager_thenConfig() { applicationContextRunner .withBean(EntityManager.class, () -> Mockito.mock(EntityManager.class)) - .withUserConfiguration(QuerydslJPAAutoConfigurationTest.ConfigurerConfiguration.class) + .withUserConfiguration(TestConfiguration.class) .run(context -> { assertThat(context).hasSingleBean(JPAQueryFactory.class); assertThat(context).hasSingleBean(JPAQueryFactoryConfigurer.class); @@ -43,7 +43,7 @@ public class QuerydslJPAAutoConfigurationTest { } @Configuration - static class ConfigurerConfiguration { + static class TestConfiguration { @Bean diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/querydsl/QuerydslSQLAutoConfigurationTest.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/querydsl/QuerydslSQLAutoConfigurationTest.java similarity index 87% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/querydsl/QuerydslSQLAutoConfigurationTest.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/querydsl/QuerydslSQLAutoConfigurationTest.java index 0628e155c5d4dd93c847a558786e94b8ced23af4..99062241ab042556fa50a1a2f88b6c58c84bcc7e 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/querydsl/QuerydslSQLAutoConfigurationTest.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/querydsl/QuerydslSQLAutoConfigurationTest.java @@ -1,12 +1,12 @@ -package io.yunjiao.springboot.autoconfigure.querydsl; +package yunjiao.springboot.autoconfigure.querydsl; import com.querydsl.sql.H2Templates; import com.querydsl.sql.MySQLTemplates; import com.querydsl.sql.SQLQueryFactory; import com.querydsl.sql.SQLTemplates; -import io.yunjiao.extension.querydsl.sql.SQLQueryCurdExecutor; -import io.yunjiao.springboot.autoconfigure.querydsl.sql.QuerydslSQLAutoConfiguration; -import io.yunjiao.springboot.autoconfigure.querydsl.sql.SQLQueryFactoryConfigurer; +import yunjiao.springboot.extension.querydsl.sql.SQLQueryCurdExecutor; +import yunjiao.springboot.autoconfigure.querydsl.sql.QuerydslSQLAutoConfiguration; +import yunjiao.springboot.autoconfigure.querydsl.sql.SQLQueryFactoryConfigurer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -34,7 +34,7 @@ public class QuerydslSQLAutoConfigurationTest { } @Test - public void giveDataSource_thenExist() { + public void givenDefault_thenConfig() { applicationContextRunner .withBean(DataSource.class, () -> mock(DataSource.class)) .withUserConfiguration(TestConfiguration.class) @@ -49,7 +49,7 @@ public class QuerydslSQLAutoConfigurationTest { } @Test - public void giveH2Template_thenUsed() { + public void givenH2Template_thenConfig() { applicationContextRunner .withBean(DataSource.class, () -> mock(DataSource.class)) .withUserConfiguration(NewSQLTemplateConfiguration.class) diff --git a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/test/TestUtils.java b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/test/TestUtils.java similarity index 90% rename from autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/test/TestUtils.java rename to autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/test/TestUtils.java index 52b624c494b00d23cfc96ce2a9c43ee32dba9eea..ac7dda23da5de6fa7474c2dbafaac6d9d497606f 100644 --- a/autoconfigure/src/test/java/io/yunjiao/springboot/autoconfigure/test/TestUtils.java +++ b/autoconfigure/src/test/java/yunjiao/springboot/autoconfigure/test/TestUtils.java @@ -1,4 +1,4 @@ -package io.yunjiao.springboot.autoconfigure.test; +package yunjiao.springboot.autoconfigure.test; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.env.Environment; diff --git a/autoconfigure/src/test/resources/logback-test.xml b/autoconfigure/src/test/resources/logback-test.xml index 689414f458aa5f658528e99e48eb80689a59a700..93c3a1ce5bae168eee10e8851ee77fef0c125736 100644 --- a/autoconfigure/src/test/resources/logback-test.xml +++ b/autoconfigure/src/test/resources/logback-test.xml @@ -1,7 +1,7 @@ - + diff --git a/bin/mvn-all-clean.cmd b/bin/mvn-all-clean.cmd new file mode 100644 index 0000000000000000000000000000000000000000..6ccf615c90da5ecf00f9c83e41865d178e5a2aa8 --- /dev/null +++ b/bin/mvn-all-clean.cmd @@ -0,0 +1,21 @@ +cd .. + +call mvn clean + +echo [starter-parent] +cd starter-parent +call mvn clean + +echo [examples] +cd .. +cd examples +call mvn clean + +echo [projects] +cd .. +cd projects +call mvn clean + +rem 切换回运行目录 +cd.. +cd bin \ No newline at end of file diff --git a/bin/mvn-all-install.cmd b/bin/mvn-all-install.cmd new file mode 100644 index 0000000000000000000000000000000000000000..345f98efc5502a08f6272f91c67465fa9ff206a3 --- /dev/null +++ b/bin/mvn-all-install.cmd @@ -0,0 +1,21 @@ +cd .. + +call mvn clean install + +echo [starter-parent] +cd starter-parent +call mvn clean install + +echo [examples] +cd .. +cd examples +call mvn clean install + +echo [projects] +cd .. +cd projects +call mvn clean install + +rem 切换回运行目录 +cd.. +cd bin \ No newline at end of file diff --git a/bin/mvn-deploy.cmd b/bin/mvn-deploy.cmd new file mode 100644 index 0000000000000000000000000000000000000000..3a7d728d776ad73d3916236269cd44fc4c167ced --- /dev/null +++ b/bin/mvn-deploy.cmd @@ -0,0 +1,11 @@ +cd .. + +call mvn clean deploy -Prelease + +echo [starter-parent] +cd starter-parent +call mvn clean deploy -Prelease + +rem 切换回运行目录 +cd.. +cd bin \ No newline at end of file diff --git a/bin/sync-github.cmd b/bin/sync-github.cmd index 59cf62efb95160d5eaeb61a2a0c25c6cda6fab75..d3af8e46ebaa023f9c804c92b939ac0735c6bb75 100644 --- a/bin/sync-github.cmd +++ b/bin/sync-github.cmd @@ -1,2 +1,3 @@ +git checkout master git pull origin master git push github master \ No newline at end of file diff --git a/dependencies/pom.xml b/dependencies/pom.xml index 1235cde22908126c6acb57eebc4b2295ecf9a1dc..4a9c5964488e243e2f14f063d47f831e8ef827ea 100644 --- a/dependencies/pom.xml +++ b/dependencies/pom.xml @@ -6,7 +6,7 @@ 4.0.0 - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot spring-boot ${revision} ../pom.xml @@ -19,13 +19,14 @@ 依赖项目 - 1.2.25 5.1.0 33.4.8-jre + 2.12.1 5.8.38 7.2.2 1.0.0 1.0.2 + 1.4.0 17 ${java.version} @@ -33,12 +34,12 @@ UTF-8 UTF-8 - 3.0.2 - 3.8.1 - 3.0.1 - 3.1.2 - 0.8.2 - 2.5.3 + 3.2.2 + 3.12.1 + 3.3.1 + 3.2.5 + 0.8.12 + 3.1.1 3.6.0 @@ -46,48 +47,63 @@ - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot autoconfigure ${revision} - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extension-common ${revision} - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extension-querydsl ${revision} - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extension-apijson ${revision} - io.gitee.yunjiao-source - spring-boot-starter-querydsl-jpa + io.gitee.yunjiao-source.spring-boot + extension-captcha ${revision} - io.gitee.yunjiao-source - spring-boot-starter-querydsl-sql + io.gitee.yunjiao-source.spring-boot + extension-id ${revision} - io.gitee.yunjiao-source - spring-boot-starter-hutool + io.gitee.yunjiao-source.spring-boot + starter-querydsl-jpa ${revision} - io.gitee.yunjiao-source - spring-boot-starter-apijson-fastjson2 + io.gitee.yunjiao-source.spring-boot + starter-querydsl-sql ${revision} - io.gitee.yunjiao-source - spring-boot-starter-apijson-gson + io.gitee.yunjiao-source.spring-boot + starter-id + ${revision} + + + io.gitee.yunjiao-source.spring-boot + starter-apijson-fastjson2 + ${revision} + + + io.gitee.yunjiao-source.spring-boot + starter-apijson-gson + ${revision} + + + io.gitee.yunjiao-source.spring-boot + starter-captcha ${revision} @@ -107,19 +123,22 @@ import - - - com.alibaba - druid-spring-boot-starter - ${druid-spring-boot-starter.version} - - com.google.guava guava ${guava.version} + + com.google.code.gson + gson + ${gson.version} + + + com.anji-plus + captcha + ${ajcaptcha.version} + @@ -160,28 +179,6 @@ - - - com.google.guava - guava - - - org.slf4j - slf4j-api - provided - - - org.projectlombok - lombok - provided - - - org.springframework.boot - spring-boot-starter-test - test - - - aliyun @@ -350,6 +347,9 @@ spring-boot-3.0.13 + + true + 3.0.13 @@ -385,9 +385,6 @@ spring-boot-3.5.4 - - true - 3.5.4 diff --git a/spring-boot-starter-apijson-gson/README.md b/doc/md/STARTER-APIJSON-FASTJSON2.md similarity index 60% rename from spring-boot-starter-apijson-gson/README.md rename to doc/md/STARTER-APIJSON-FASTJSON2.md index d630ac64dd5761558845f78963cf62bd4ce267a9..5e64d1c76ec2fd47d462d10f214057ce079ad6ad 100644 --- a/spring-boot-starter-apijson-gson/README.md +++ b/doc/md/STARTER-APIJSON-FASTJSON2.md @@ -1,27 +1,26 @@ -# spring-boot-starter-apijson-gson +# starter-apijson-fastjson2 +集成`APIJSON`框架的启动器, 使用`apijson-fastjson2`插件 -## 使用指南 +* 方便配置。在`application.yml`中配置参数,避免写死在程序中。所有的配置属性参考[application-all.yaml](../../examples/example-apijson-fastjson2/src/main/resources/application-all.yml) +* 支持数据库连接池 +* 提供多个接口,如:CRUD,登录, 登出等 -参考示例项目`spring-boot-examples/spring-boot-example-apijson-gson` - -在pom.xml中添加 +详细使用参考示例[example-apijson-fastjson2](../../examples/example-apijson-fastjson2) +## 使用Maven +在`pom.xml`中添加依赖 ```xml - - io.gitee.yunjiao-source - spring-boot-starter-apijson-fastjson2 + io.gitee.yunjiao-source.spring-boot + starter-apijson-fastjson2 ${version} ``` -## 所有的配置属性 - -参考[application-all.yaml](../doc/apijson/application-all.yml) - ## 支持的接口 + | 接口url | 方法 | 说明 | |-----------------------|------|--------------------------------------------------| | common/{method} | POST | 支持GET,HEAD,GETS,HEADS,POST,PUT,DELETE,CRUD等 | @@ -35,19 +34,4 @@ | ext/register | POST | 注册 | | ext/put/password | POST | 设置密码 | -请求示例 - -```curl -curl --location --request POST 'http://localhost:8080/api-json/common/get' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "Moment": { - "id": 12 - } -}' -``` - -* 接口默认是开启的,可以关闭这些接口,配置属性 `spring.apijson.rest-api.enable=false` -* 接口添加了统一的前缀,默认是`api-json`,配置属性`spring.apijson.rest-api.prefix=YOURE-PREFIX` -* 在`doc/apijson`目录下有`apifox`及`postman`工具文件,导入json文件 diff --git a/spring-boot-starter-apijson-fastjson2/README.md b/doc/md/STARTER-APIJSON-GSON.md similarity index 60% rename from spring-boot-starter-apijson-fastjson2/README.md rename to doc/md/STARTER-APIJSON-GSON.md index 06c02cc8e226247baa216d91aeff1af52e3744de..96f5e762a7f404b9f11fdf0550df64085502d6f2 100644 --- a/spring-boot-starter-apijson-fastjson2/README.md +++ b/doc/md/STARTER-APIJSON-GSON.md @@ -1,27 +1,26 @@ -# spring-boot-starter-apijson-fastjson2 +# starter-apijson-gson +集成`APIJSON`框架的启动器, 使用`apijson-gson`插件 -## 使用指南 +* 方便配置。在`application.yml`中配置参数,避免写死在程序中。所有的配置属性参考[application-all.yaml](../../examples/example-apijson-gson/src/main/resources/application-all.yml) +* 支持数据库连接池 +* 提供多个接口,如:CRUD,登录, 登出等 -参考示例项目`spring-boot-examples/spring-boot-example-apijson-fastjson2` - -在pom.xml中添加 +详细使用参考示例[example-apijson-gson](../../examples/example-apijson-gson) +## 使用Maven +在`pom.xml`中添加依赖 ```xml - - io.gitee.yunjiao-source - spring-boot-starter-apijson-fastjson2 + io.gitee.yunjiao-source.spring-boot + starter-apijson-gson ${version} ``` -## 所有的配置属性 - -参考[application-all.yaml](../doc/apijson/application-all.yml) - ## 支持的接口 + | 接口url | 方法 | 说明 | |-----------------------|------|--------------------------------------------------| | common/{method} | POST | 支持GET,HEAD,GETS,HEADS,POST,PUT,DELETE,CRUD等 | @@ -35,20 +34,4 @@ | ext/register | POST | 注册 | | ext/put/password | POST | 设置密码 | -请求示例 - -```curl -curl --location --request POST 'http://localhost:8080/api-json/common/get' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "Moment": { - "id": 12 - } -}' -``` - -* 接口默认是开启的,可以关闭这些接口,配置属性 `spring.apijson.rest-api.enable=false` -* 接口添加了统一的前缀,默认是`api-json`,配置属性`spring.apijson.rest-api.prefix=YOURE-PREFIX` -* 在`doc/apijson`目录下有`apifox`及`postman`工具文件,导入json文件 - diff --git a/doc/md/STARTER-CAPTCHA.md b/doc/md/STARTER-CAPTCHA.md new file mode 100644 index 0000000000000000000000000000000000000000..1f6161b45d73a7bdee902c049be89d962e24a03d --- /dev/null +++ b/doc/md/STARTER-CAPTCHA.md @@ -0,0 +1,23 @@ +# start-captcha + +验证码生成启动器,集成`Hutool`,`aj-captcha`等框架 + +* 零配置。无需在yaml中配置参数,框架提供默认值 +* 支持多种验证码,包括:线段干扰验证码,圆圈干扰验证码,扭曲干扰验证码,GIF验证码,滑块拼图验证码,文字点选验证码,旋转拼图验证码 +* 提供丰富的配置参数,支持用户自定义。所有的配置参数参考[application-all.yml](../../examples/example-captcha/src/main/resources/application-all.yml) + +详细使用参考示例[example-captcha](../../examples/example-captcha) + +## 使用Maven + +在`pom.xml`中添加依赖 +```xml + + io.gitee.yunjiao-source.spring-boot + starter-captcha + ${version} + +``` + + + diff --git a/doc/md/STARTER-ID.md b/doc/md/STARTER-ID.md new file mode 100644 index 0000000000000000000000000000000000000000..c5acf504a4b5a71225208da64da7cf58bc8466b7 --- /dev/null +++ b/doc/md/STARTER-ID.md @@ -0,0 +1,23 @@ +## start-id + +ID生成启动器,集成`Hutool`等框架 + +* Snowflake: 雪花算法。默认workerId=1,datacenterId=1。如需支持分布式,请设置系统环境变量:SNOWFLAKE_WORKER_ID 与 {SNOWFLAKE_DATACENTER_ID}。使用属性`spring.hutool.snowflak=false`可关闭配置 + +详细使用参考示例[example-id](../../examples/example-id) + +## 使用Maven + +在`pom.xml`中添加依赖 +```xml + + io.gitee.yunjiao-source.spring-boot + starter-id + ${version} + +``` + + + + + diff --git a/doc/md/STARTER-QUERYDSL-JPA.md b/doc/md/STARTER-QUERYDSL-JPA.md new file mode 100644 index 0000000000000000000000000000000000000000..ef0706c7b38893542606a17881bc55ec119753e5 --- /dev/null +++ b/doc/md/STARTER-QUERYDSL-JPA.md @@ -0,0 +1,21 @@ +## start-querydsl-jpa + +集成`QueryDSL JPA`框架的启动器。 + +* `JPAQueryRepositorySupport`仓库类,用户继承此类,集成功能:单个查询,列表查询,查询分页,查询Tuple,统计记录数,更新,删除等。支持数据库事务 +* `QSpecification`接口,用于复杂条件查询,支持:and, or, not等。类似`Spring`框架的`Specification` + + +详细使用参考示例[example-querydsl-jpa](../../examples/example-querydsl-jpa) + +## 使用Maven + +在`pom.xml`中添加依赖 +```xml + + io.gitee.yunjiao-source.spring-boot + starter-querydsl-jpa + ${version} + +``` + diff --git a/doc/md/STARTER-QUERYDSL-SQL.md b/doc/md/STARTER-QUERYDSL-SQL.md new file mode 100644 index 0000000000000000000000000000000000000000..43d48d6376ec70e6ec44acba9316312c865e2d2f --- /dev/null +++ b/doc/md/STARTER-QUERYDSL-SQL.md @@ -0,0 +1,21 @@ +## start-querydsl-sql + +集成`QueryDSL SQL`框架的启动器。 + +* `SQLQueryRepositorySupport`仓库类,用户继承此类,集成功能:单个查询,列表查询,查询分页,查询Tuple,统计记录数,更新,删除等。支持数据库事务 +* `QSpecification`接口,用于复杂条件查询,支持:and, or, not等。类似`Spring`框架的`Specification` + + +详细使用参考示例[example-querydsl-sql](../../examples/example-querydsl-sql) + +## 使用Maven + +在`pom.xml`中添加依赖 +```xml + + io.gitee.yunjiao-source.spring-boot + starter-querydsl-sql + ${version} + +``` + diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000000000000000000000000000000000000..af700d09a09d074018e13801e88e74c72c9b844f --- /dev/null +++ b/examples/README.md @@ -0,0 +1,36 @@ +# examples + +示例项目 + +## example-apijson-fastjson2 + +基于`starter-apijson-fastjson2`示例项目。在启动项目之前,需要配置数据库,并运行脚本,具体查看`resources`目录。 +成功启动服务后,就可以访问服务提供的接口。在doc/apijson下,有apifox,postman工具文件。 + +## example-apijson-gson + +基于`starter-apijson-gson`示例项目。在启动项目之前,需要配置数据库,并运行脚本,具体查看`resources`目录。 +成功启动服务后,就可以访问服务提供的接口。在doc/apijson下,有apifox,postman工具文件。 + +** 注意 +在服务启动过程中,会出现异常,这是因为官方提供的gson插件还存在问题。有些接口请求也会出现异常 + +## example-id + +基于`starter-id`示例项目。 + +## example-querydsl-jpa + +基于`starter-querydsl-jpa`示例项目。需要配置数据库及运行数据库脚本,请查看`resources`目录。 + +## example-querydsl-sql + +基于`starter-querydsl-sql`示例项目。需要配置数据库及运行数据库脚本,请查看`resources`目录。 + +## example-captcha + +验证码示例项目 + + + + diff --git a/examples/example-apijson-fastjson2/pom.xml b/examples/example-apijson-fastjson2/pom.xml index a620d10a8cc5266dfc90796e4f65cf20164680b7..37c439fc732152d5ac6146160f0311afa6c22be8 100644 --- a/examples/example-apijson-fastjson2/pom.xml +++ b/examples/example-apijson-fastjson2/pom.xml @@ -3,7 +3,7 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot examples ${revision} @@ -16,8 +16,8 @@ - io.gitee.yunjiao-source - spring-boot-starter-apijson-fastjson2 + io.gitee.yunjiao-source.spring-boot + starter-apijson-fastjson2 diff --git a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/ApijsonFastjson2Configuration.java b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/ApijsonFastjson2Configuration.java similarity index 84% rename from examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/ApijsonFastjson2Configuration.java rename to examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/ApijsonFastjson2Configuration.java index f6b2532c8a0a60c924c37a78940ad84183e0e680..bcb39def2aad7be9990ab7ce38af9858a97be65c 100644 --- a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/ApijsonFastjson2Configuration.java +++ b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/ApijsonFastjson2Configuration.java @@ -1,8 +1,8 @@ -package io.yunjiao.example.apijson; +package yunjiao.springboot.example.apijson; -import io.yunjiao.example.apijson.fastjson2.CustomFastjson2Creator; -import io.yunjiao.extension.apjson.util.ApijsonConsts; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; +import yunjiao.springboot.example.apijson.fastjson2.CustomFastjson2Creator; +import yunjiao.springboot.extension.apjson.util.ApijsonConsts; +import yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; import jakarta.annotation.Nonnull; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; diff --git a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/ApijsonFastjson2ExampleApplication.java b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/ApijsonFastjson2ExampleApplication.java similarity index 89% rename from examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/ApijsonFastjson2ExampleApplication.java rename to examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/ApijsonFastjson2ExampleApplication.java index 1df154e53e37ee035c67176f8c25405f8c70690b..2ae8211c49803e38cdd7ffc52f0d17ea865cd2b7 100644 --- a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/ApijsonFastjson2ExampleApplication.java +++ b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/ApijsonFastjson2ExampleApplication.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.apijson; +package yunjiao.springboot.example.apijson; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/config/CustomFunctionParserConfigurer.java b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/config/CustomFunctionParserConfigurer.java similarity index 82% rename from examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/config/CustomFunctionParserConfigurer.java rename to examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/config/CustomFunctionParserConfigurer.java index 411575ddfa4702db8106f8de973fdd85b73179ca..ec3d9edbc00c3edb09844d8e1360880501d31322 100644 --- a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/config/CustomFunctionParserConfigurer.java +++ b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/config/CustomFunctionParserConfigurer.java @@ -1,8 +1,8 @@ -package io.yunjiao.example.apijson.config; +package yunjiao.springboot.example.apijson.config; import apijson.orm.script.JavaScriptExecutor; import apijson.orm.script.ScriptExecutor; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonFunctionParserConfigurer; +import yunjiao.springboot.autoconfigure.apijson.ApijsonFunctionParserConfigurer; import org.springframework.context.annotation.Configuration; import java.util.List; diff --git a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/config/CustomSqlConfigConfigurer.java b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/config/CustomSqlConfigConfigurer.java similarity index 97% rename from examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/config/CustomSqlConfigConfigurer.java rename to examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/config/CustomSqlConfigConfigurer.java index 7c27253ca5cdbd60b00fff22e50c53f3bf26ac76..d3a6ee00824d872a6fc4a0efc63c24905e1c7b2c 100644 --- a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/config/CustomSqlConfigConfigurer.java +++ b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/config/CustomSqlConfigConfigurer.java @@ -1,7 +1,7 @@ -package io.yunjiao.example.apijson.config; +package yunjiao.springboot.example.apijson.config; import apijson.StringUtil; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonSqlConfigConfigurer; +import yunjiao.springboot.autoconfigure.apijson.ApijsonSqlConfigConfigurer; import org.springframework.context.annotation.Configuration; import java.util.Arrays; diff --git a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/config/CustomVerifierConfigurer.java b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/config/CustomVerifierConfigurer.java similarity index 87% rename from examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/config/CustomVerifierConfigurer.java rename to examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/config/CustomVerifierConfigurer.java index a0f8a0c0ba38256d0d74dfc671cb4fefc5978dc9..f74268ece38454b4dcaf923bde9aa5c80b2752c1 100644 --- a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/config/CustomVerifierConfigurer.java +++ b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/config/CustomVerifierConfigurer.java @@ -1,9 +1,9 @@ -package io.yunjiao.example.apijson.config; +package yunjiao.springboot.example.apijson.config; import apijson.RequestMethod; import apijson.StringUtil; import apijson.orm.Entry; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonVerifierConfigurer; +import yunjiao.springboot.autoconfigure.apijson.ApijsonVerifierConfigurer; import org.springframework.context.annotation.Configuration; import java.util.List; diff --git a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/fastjson2/CustomFastjson2Creator.java b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/fastjson2/CustomFastjson2Creator.java similarity index 71% rename from examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/fastjson2/CustomFastjson2Creator.java rename to examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/fastjson2/CustomFastjson2Creator.java index bc16192ccd27995e3d25be649f23400df5aa9282..995363a8be67dcfdbf63882c69e3d1ea28818267 100644 --- a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/fastjson2/CustomFastjson2Creator.java +++ b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/fastjson2/CustomFastjson2Creator.java @@ -1,8 +1,8 @@ -package io.yunjiao.example.apijson.fastjson2; +package yunjiao.springboot.example.apijson.fastjson2; import apijson.fastjson2.APIJSONFunctionParser; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; -import io.yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2Creator; +import yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; +import yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2Creator; import javax.sql.DataSource; import java.io.Serializable; diff --git a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/fastjson2/CustomFastjson2FunctionParser.java b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/fastjson2/CustomFastjson2FunctionParser.java similarity index 94% rename from examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/fastjson2/CustomFastjson2FunctionParser.java rename to examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/fastjson2/CustomFastjson2FunctionParser.java index eb5e6bcd930ea7de7531e873a61185a5373d8d96..a8271170e655d4eca46fecf2001e73aa5486c662 100644 --- a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/fastjson2/CustomFastjson2FunctionParser.java +++ b/examples/example-apijson-fastjson2/src/main/java/yunjiao/springboot/example/apijson/fastjson2/CustomFastjson2FunctionParser.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.apijson.fastjson2; +package yunjiao.springboot.example.apijson.fastjson2; import apijson.NotNull; import apijson.RequestMethod; @@ -10,10 +10,10 @@ import apijson.orm.AbstractVerifier; import apijson.orm.Visitor; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonUtils; -import io.yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2FunctionParser; -import io.yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2Parser; -import io.yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2Verifier; +import yunjiao.springboot.autoconfigure.apijson.ApijsonUtils; +import yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2FunctionParser; +import yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2Parser; +import yunjiao.springboot.autoconfigure.apijson.fastjson2.Fastjson2Verifier; import java.io.Serializable; import java.util.ArrayList; diff --git a/doc/apijson/application-all.yml b/examples/example-apijson-fastjson2/src/main/resources/application-all.yml similarity index 100% rename from doc/apijson/application-all.yml rename to examples/example-apijson-fastjson2/src/main/resources/application-all.yml diff --git a/examples/example-apijson-fastjson2/src/main/resources/application.yml b/examples/example-apijson-fastjson2/src/main/resources/application.yml index 824b509625ba43d1baf9b5bdea787943acb4e6d5..eabfdfa1faa864d60264f5b8e5bb5d6c29ff2442 100644 --- a/examples/example-apijson-fastjson2/src/main/resources/application.yml +++ b/examples/example-apijson-fastjson2/src/main/resources/application.yml @@ -22,5 +22,5 @@ logging: level: root: info org.springframework.boot.autoconfigure: info - io.yunjiao: debug + yunjiao.springboot: debug diff --git a/examples/example-apijson-gson/pom.xml b/examples/example-apijson-gson/pom.xml index cb1e8f7d342dbb14c27c64e30b1d3b0e7d1719a4..59de71f1fdf206ae530da1d2a6609fd8e4fb0f7a 100644 --- a/examples/example-apijson-gson/pom.xml +++ b/examples/example-apijson-gson/pom.xml @@ -3,7 +3,7 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot examples ${revision} @@ -16,8 +16,8 @@ - io.gitee.yunjiao-source - spring-boot-starter-apijson-gson + io.gitee.yunjiao-source.spring-boot + starter-apijson-gson diff --git a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/ApijsonGsonConfiguration.java b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/ApijsonGsonConfiguration.java similarity index 85% rename from examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/ApijsonGsonConfiguration.java rename to examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/ApijsonGsonConfiguration.java index 863f6906d49ec7235922a7004ba7548e235fb4a5..180134903102cac5bde2f66526184c28df53eab0 100644 --- a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/ApijsonGsonConfiguration.java +++ b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/ApijsonGsonConfiguration.java @@ -1,8 +1,8 @@ -package io.yunjiao.example.apijson; +package yunjiao.springboot.example.apijson; -import io.yunjiao.example.apijson.gson.CustomGsonCreator; -import io.yunjiao.extension.apjson.util.ApijsonConsts; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; +import yunjiao.springboot.example.apijson.gson.CustomGsonCreator; +import yunjiao.springboot.extension.apjson.util.ApijsonConsts; +import yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; import jakarta.annotation.Nonnull; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; diff --git a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/ApijsonGsonExampleApplication.java b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/ApijsonGsonExampleApplication.java similarity index 89% rename from examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/ApijsonGsonExampleApplication.java rename to examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/ApijsonGsonExampleApplication.java index 1f86e6874109e67d61f86d7d5fa176293d6ffcc4..c6e460914f2d55765d638532b137b40f687e170a 100644 --- a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/ApijsonGsonExampleApplication.java +++ b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/ApijsonGsonExampleApplication.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.apijson; +package yunjiao.springboot.example.apijson; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/config/CustomFunctionParserConfigurer.java b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/config/CustomFunctionParserConfigurer.java similarity index 82% rename from examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/config/CustomFunctionParserConfigurer.java rename to examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/config/CustomFunctionParserConfigurer.java index 411575ddfa4702db8106f8de973fdd85b73179ca..ec3d9edbc00c3edb09844d8e1360880501d31322 100644 --- a/examples/example-apijson-fastjson2/src/main/java/io/yunjiao/example/apijson/config/CustomFunctionParserConfigurer.java +++ b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/config/CustomFunctionParserConfigurer.java @@ -1,8 +1,8 @@ -package io.yunjiao.example.apijson.config; +package yunjiao.springboot.example.apijson.config; import apijson.orm.script.JavaScriptExecutor; import apijson.orm.script.ScriptExecutor; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonFunctionParserConfigurer; +import yunjiao.springboot.autoconfigure.apijson.ApijsonFunctionParserConfigurer; import org.springframework.context.annotation.Configuration; import java.util.List; diff --git a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/config/CustomSqlConfigConfigurer.java b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/config/CustomSqlConfigConfigurer.java similarity index 97% rename from examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/config/CustomSqlConfigConfigurer.java rename to examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/config/CustomSqlConfigConfigurer.java index 7c27253ca5cdbd60b00fff22e50c53f3bf26ac76..d3a6ee00824d872a6fc4a0efc63c24905e1c7b2c 100644 --- a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/config/CustomSqlConfigConfigurer.java +++ b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/config/CustomSqlConfigConfigurer.java @@ -1,7 +1,7 @@ -package io.yunjiao.example.apijson.config; +package yunjiao.springboot.example.apijson.config; import apijson.StringUtil; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonSqlConfigConfigurer; +import yunjiao.springboot.autoconfigure.apijson.ApijsonSqlConfigConfigurer; import org.springframework.context.annotation.Configuration; import java.util.Arrays; diff --git a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/config/CustomVerifierConfigurer.java b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/config/CustomVerifierConfigurer.java similarity index 87% rename from examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/config/CustomVerifierConfigurer.java rename to examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/config/CustomVerifierConfigurer.java index a0f8a0c0ba38256d0d74dfc671cb4fefc5978dc9..f74268ece38454b4dcaf923bde9aa5c80b2752c1 100644 --- a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/config/CustomVerifierConfigurer.java +++ b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/config/CustomVerifierConfigurer.java @@ -1,9 +1,9 @@ -package io.yunjiao.example.apijson.config; +package yunjiao.springboot.example.apijson.config; import apijson.RequestMethod; import apijson.StringUtil; import apijson.orm.Entry; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonVerifierConfigurer; +import yunjiao.springboot.autoconfigure.apijson.ApijsonVerifierConfigurer; import org.springframework.context.annotation.Configuration; import java.util.List; diff --git a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/gson/CustomGsonCreator.java b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/gson/CustomGsonCreator.java similarity index 72% rename from examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/gson/CustomGsonCreator.java rename to examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/gson/CustomGsonCreator.java index 704d6c12f3707e5000f7382f77b2bf6e372a9625..50465d72042b33429a6b8d989c07c93f814a7b34 100644 --- a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/gson/CustomGsonCreator.java +++ b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/gson/CustomGsonCreator.java @@ -1,8 +1,8 @@ -package io.yunjiao.example.apijson.gson; +package yunjiao.springboot.example.apijson.gson; import apijson.gson.APIJSONFunctionParser; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; -import io.yunjiao.springboot.autoconfigure.apijson.gson.GsonCreator; +import yunjiao.springboot.autoconfigure.apijson.ApijsonSqlProperties; +import yunjiao.springboot.autoconfigure.apijson.gson.GsonCreator; import javax.sql.DataSource; import java.io.Serializable; diff --git a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/gson/CustomGsonFunctionParser.java b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/gson/CustomGsonFunctionParser.java similarity index 95% rename from examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/gson/CustomGsonFunctionParser.java rename to examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/gson/CustomGsonFunctionParser.java index f931dace433dd3e7da90f1848dd1e25cd54d6bed..d4e534cef01b90d45316b206a2257a7282b878cc 100644 --- a/examples/example-apijson-gson/src/main/java/io/yunjiao/example/apijson/gson/CustomGsonFunctionParser.java +++ b/examples/example-apijson-gson/src/main/java/yunjiao/springboot/example/apijson/gson/CustomGsonFunctionParser.java @@ -1,13 +1,13 @@ -package io.yunjiao.example.apijson.gson; +package yunjiao.springboot.example.apijson.gson; import apijson.JSONRequest; import apijson.NotNull; import apijson.StringUtil; import apijson.orm.AbstractVerifier; import apijson.orm.Visitor; -import io.yunjiao.springboot.autoconfigure.apijson.ApijsonUtils; -import io.yunjiao.springboot.autoconfigure.apijson.gson.GsonFunctionParser; -import io.yunjiao.springboot.autoconfigure.apijson.gson.GsonVerifier; +import yunjiao.springboot.autoconfigure.apijson.ApijsonUtils; +import yunjiao.springboot.autoconfigure.apijson.gson.GsonFunctionParser; +import yunjiao.springboot.autoconfigure.apijson.gson.GsonVerifier; import java.io.Serializable; import java.util.ArrayList; diff --git a/examples/example-apijson-gson/src/main/resources/application-all.yml b/examples/example-apijson-gson/src/main/resources/application-all.yml new file mode 100644 index 0000000000000000000000000000000000000000..974ae8a9ce3072938c1f11fbef806239289d154f --- /dev/null +++ b/examples/example-apijson-gson/src/main/resources/application-all.yml @@ -0,0 +1,43 @@ +# 所有的配置属性 +spring: + apijson: + rest-api: + enable: true # 是否初始化Rest接口,默认true。框架已提供APIJSON统一接口实现 + prefix: api-json # Rest接口前缀,默认api-json。访问接口如:http://localhost:8080/api-json/common/get + application: gson # 集成apijson-fastjson2包 + new-id-strategy: timestamp # 主键生成策略,默认timestamp。支持:database(数据库自增),uuid(uuid字符串), timestamp(当前时间毫秒数),snowflake(雪花算法),custom(用户自定义) + need-verify-login: true # 每次访问Rest接口时是否需要校验登录 + need-verify-role: true # 每次访问Rest接口时是否需要校验角色权限 + need-verify-content: true # 每次访问Rest接口时开启校验请求传参内容 + enable-on-startup: false # 在启动时初始化,如:APIJSONVerifier(校验器)初始化 + shutdown-when-server-error: true # 启动遇到异常时停止 + log-debug: false # 日志 + sql: + config: + enable-column-config: false # 支持 !key 反选字段 和 字段名映射, 默认false + default-database: MYSQL # 默认的数据库类型, 默认MYSQL。支持多种数据库,请参考SQLConfig类定义,注意名称全大写 + default-schema: sys # 默认数据库名/模式,默认sys。 设置含有APIJSON系统表的数据库 + default-catalog: + default-namespace: + version: 5.7.22 # 数据库版本, 默认'5.7.22' + executor: + enable-output-null-column: false # 是否返回 值为null的字段, 默认false + key-raw-list: '@RAW@LIST' + key-vice-item: '@VICE@ITEM' + parser: + function: + parse-arg-value: false # 是否解析参数 key 的对应的值 + enable-remote-function: true # 开启支持远程函数 + enable-script-function: true # 开启支持远程函数中的 JavaScript 脚本形式 + request: + print-request-string-log: false # 是否打印关键的接口请求内容 + print-big-log: false # 打印大数据量日志的标识 + print-request-endtime-log: false # 是否打印关键的接口请求结束时间 + return-stack-trace: true # 控制返回 trace:stack 字段 + start-from1: false # 分页页码是否从 1 开始,默认为从 0 开始 + verifier: + enable-verify-column: true + enable-apijson-router: false + update-must-have-id-condition: true # 为 PUT, DELETE 强制要求必须有 id/id{}/id{}@ 条件 + enable-verify-role: true # 开启校验请求角色权限 + enable-verify-content: true # 开启校验请求传参内容 diff --git a/examples/example-apijson-gson/src/main/resources/application.yml b/examples/example-apijson-gson/src/main/resources/application.yml index 36bae44c7b36c217ee33b4ebe11f7baab6e63d0d..ecf479d45bcf2b9d1fa65c1743cf7701190e55e8 100644 --- a/examples/example-apijson-gson/src/main/resources/application.yml +++ b/examples/example-apijson-gson/src/main/resources/application.yml @@ -23,5 +23,5 @@ logging: level: root: info org.springframework.boot.autoconfigure: info - io.yunjiao: debug + yunjiao.springboot: debug diff --git a/examples/example-captcha/pom.xml b/examples/example-captcha/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..3e883178a4222fd592a39a45d8140354921d0714 --- /dev/null +++ b/examples/example-captcha/pom.xml @@ -0,0 +1,40 @@ + + + + io.gitee.yunjiao-source.spring-boot + examples + ${revision} + + 4.0.0 + + example-captcha + jar + Example :: Captcha + Captcha 示例应用 + + + + io.gitee.yunjiao-source.spring-boot + starter-captcha + + + + cn.hutool + hutool-cache + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-webflux + + + + + + \ No newline at end of file diff --git a/examples/example-captcha/src/main/java/yunjiao/springboot/example/captcha/CaptchaCommandLineRunner.java b/examples/example-captcha/src/main/java/yunjiao/springboot/example/captcha/CaptchaCommandLineRunner.java new file mode 100644 index 0000000000000000000000000000000000000000..ccb1e2f055841aa978608f0ecf13f48c8ffa0ae2 --- /dev/null +++ b/examples/example-captcha/src/main/java/yunjiao/springboot/example/captcha/CaptchaCommandLineRunner.java @@ -0,0 +1,69 @@ +package yunjiao.springboot.example.captcha; + +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.captcha.CaptchaService; +import yunjiao.springboot.autoconfigure.captcha.CaptchaServiceFactory; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * 示例 + * + * @author yangyunjiao + */ +@Slf4j +@Component +public class CaptchaCommandLineRunner implements CommandLineRunner { + @Autowired + private CaptchaServiceFactory factory; + + @Override + public void run(String... args) throws Exception { + CaptchaService circleService = factory.findService(CaptchaCategory.circle); + CaptchaData data = circleService.draw(); + saveImage(data); + + CaptchaService lineService = factory.findService(CaptchaCategory.line); + data = lineService.draw(); + saveImage(data); + + CaptchaService gifService = factory.findService(CaptchaCategory.gif); + data = gifService.draw(); + saveImage(data); + + CaptchaService shearService = factory.findService(CaptchaCategory.shear); + data = shearService.draw(); + saveImage(data); + + CaptchaService blockPuzzleService = factory.findService(CaptchaCategory.blockPuzzle); + data = blockPuzzleService.draw(); + saveImage(data); + + CaptchaService clickWordService = factory.findService(CaptchaCategory.clickWord); + data = clickWordService.draw(); + saveImage(data); + } + + private void saveImage(CaptchaData data) throws IOException { + Path targetDir = Paths.get("target", "processed-images"); + if (!Files.exists(targetDir)) { + Files.createDirectories(targetDir); + } + + Path filePath = targetDir.resolve(data.category().name() + "-captcha." + data.category().getExt()); + Files.write(filePath, data.captchaImage()); + + if (data.backgroundImage() != null) { + filePath = targetDir.resolve(data.category().name() + "-background." + data.category().getExt()); + Files.write(filePath, data.backgroundImage()); + } + } +} diff --git a/examples/example-captcha/src/main/java/yunjiao/springboot/example/captcha/CaptchaController.java b/examples/example-captcha/src/main/java/yunjiao/springboot/example/captcha/CaptchaController.java new file mode 100644 index 0000000000000000000000000000000000000000..ee506fa81e2e5b51c0ec0612adcd550bb582f975 --- /dev/null +++ b/examples/example-captcha/src/main/java/yunjiao/springboot/example/captcha/CaptchaController.java @@ -0,0 +1,53 @@ +package yunjiao.springboot.example.captcha; + +import cn.hutool.cache.CacheUtil; +import cn.hutool.cache.impl.TimedCache; +import yunjiao.springboot.autoconfigure.captcha.CaptchaServiceFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; +import yunjiao.springboot.extension.common.captcha.*; + +/** + * 接口 + * + * @author yangyunjiao + */ +@RestController +@RequiredArgsConstructor +public class CaptchaController { + private final CaptchaServiceFactory factory; + private final TimedCache timedCache = CacheUtil.newTimedCache(30 * 1000); + + @GetMapping("/captcha") + public CaptchaReponse get(@RequestParam(name = "category") CaptchaCategory category) { + CaptchaService service = factory.findService(category); + CaptchaData data = service.draw(); + + CaptchaReponse reponse = new CaptchaReponse(); + reponse.setKey(data.key()); + reponse.setCategory(service.getCategory()); + reponse.setCaptchaImageBase64(data.captchaImageBase64Url()); + reponse.setBackgroundImageBase64(data.backgroundImageBase64Url()); + + timedCache.put(data.key(), data.code()); + System.out.println("code=" + data.code()); + return reponse; + } + + @PostMapping("/captcha") + public String post(@RequestBody CaptchaValidate validate) { + String cacheCode = timedCache.get(validate.getKey()); + if (!StringUtils.hasText(cacheCode)) { + return "验证码校验失败"; + } + + CaptchaService service = factory.findService(validate.getCategory()); + boolean pass = service.verify(cacheCode, validate.getCode()); + if (pass) { + return "验证码校验成功"; + } else { + return "验证码校验失败"; + } + } +} diff --git a/examples/example-captcha/src/main/java/yunjiao/springboot/example/captcha/CaptchaExampleApplication.java b/examples/example-captcha/src/main/java/yunjiao/springboot/example/captcha/CaptchaExampleApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..f53fb74774ffed57c232cf64f2ca1d8829b43252 --- /dev/null +++ b/examples/example-captcha/src/main/java/yunjiao/springboot/example/captcha/CaptchaExampleApplication.java @@ -0,0 +1,16 @@ +package yunjiao.springboot.example.captcha; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * 程序入口 + * + * @author yangyunjiao + */ +@SpringBootApplication +public class CaptchaExampleApplication { + public static void main(String[] args) { + SpringApplication.run(CaptchaExampleApplication.class, args); + } +} diff --git a/examples/example-captcha/src/main/resources/application-all.yml b/examples/example-captcha/src/main/resources/application-all.yml new file mode 100644 index 0000000000000000000000000000000000000000..e2b2161976b0bb9f54d3463f639d3d821bd08ab6 --- /dev/null +++ b/examples/example-captcha/src/main/resources/application-all.yml @@ -0,0 +1,69 @@ +spring: + captcha: + # + hutool: + line: + width: 250 # 图片的宽度, 默认:250 + height: 50 # 图片的高度, 默认: 50 + interfere-count: 60 # 验证码干扰元素个数, 默认:60 + background-color: white # 背景色, 默认:white + #transparency: # 文字透明度,取值0~1,1表示不透明, 默认:null + fuzziness: 2 # 模糊度(0 - 30), 默认:2 + valid-ignore-case: true # 校验时忽略大小写 , 默认:true + font: # 字体 + #name: # 名称, 为空表示使用系统默认字体 ,默认: null + style: plain # 风格, 默认:plain + size: 36 # 大小, 默认:36 + code: # 码属性 + generator: numandchar # 码生成类型,默认:numandchar + length: 5 # 字符长度, 默认:5 + circle: + width: 250 # 图片的宽度, 默认:250 + height: 50 # 图片的高度, 默认: 50 + interfere-count: 30 # 验证码干扰元素个数, 默认:30 + background-color: white # 背景色, 默认:white + #transparency: # 文字透明度,取值0~1,1表示不透明, 默认:null + fuzziness: 2 # 模糊度(0 - 30), 默认:2 + valid-ignore-case: true # 校验时忽略大小写 , 默认:true + font: # 字体 + #name: # 名称, 为空表示使用系统默认字体 ,默认: null + style: plain # 风格, 默认:plain + size: 36 # 大小, 默认:36 + code: # 码 + generator: numandchar # 码生成类型,默认:numandchar + length: 5 # 字符长度, 默认:5 + shear: + width: 250 # 图片的宽度, 默认:250 + height: 50 # 图片的高度, 默认: 50 + interfere-count: 4 # 验证码干扰线宽度, 默认:4 + background-color: white # 背景色, 默认:white + #transparency: # 文字透明度,取值0~1,1表示不透明, 默认:null + fuzziness: 2 # 模糊度(0 - 30), 默认:2 + valid-ignore-case: true # 校验时忽略大小写 , 默认:true + font: # 字体 + #name: # 名称, 为空表示使用系统默认字体 ,默认: null + style: plain # 风格, 默认:plain + size: 36 # 大小, 默认:36 + code: # 码 + generator: numandchar # 码生成类型,默认:numandchar + length: 5 # 字符长度, 默认:5 + gif: + width: 250 # 图片的宽度, 默认:250 + height: 50 # 图片的高度, 默认: 50 + interfere-count: 10 # 验证码干扰元素个数, 默认:10 + background-color: white # 背景色, 默认:white + #transparency: # 文字透明度,取值0~1,1表示不透明, 默认:null + fuzziness: 2 # 模糊度(0 - 30), 默认:2 + valid-ignore-case: true # 校验时忽略大小写 , 默认:true + font: # 字体 + #name: # 名称, 为空表示使用系统默认字体 ,默认: null + style: plain # 风格, 默认:plain + size: 36 # 大小, 默认:36 + code: # 码 + generator: numandchar # 码生成类型,默认:numandchar + length: 5 # 字符长度, 默认:5 + quality: 10 # 量化器取样间隔, 1 ~ 20 值之间 - 默认是10 + repeat: 0 # 帧循环次数,默认是 0, 意味着无限循环 + min-color: 0 # 设置随机颜色时,最小的取色范围 + max-color: 255 # 设置随机颜色时,最大的取色范围 + diff --git a/examples/example-captcha/src/main/resources/application.yml b/examples/example-captcha/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..0ce114fbbedf9351fd99fc96b94383acfe74d9a7 --- /dev/null +++ b/examples/example-captcha/src/main/resources/application.yml @@ -0,0 +1,7 @@ + +logging: + level: + root: info + org.springframework.boot.autoconfigure: info + yunjiao.springboot: debug + diff --git a/examples/example-hutool/pom.xml b/examples/example-id/pom.xml similarity index 69% rename from examples/example-hutool/pom.xml rename to examples/example-id/pom.xml index 4c2645120faf0c97e9d1a23bcf1eb6551a211cb1..bd84146e82ee83aef0de2ac1fae38976e58a83eb 100644 --- a/examples/example-hutool/pom.xml +++ b/examples/example-id/pom.xml @@ -3,21 +3,21 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot examples ${revision} 4.0.0 - example-hutool + example-id jar - Example :: Hutool - Hutool 示例应用 + Example :: Id + Id 示例应用 - io.gitee.yunjiao-source - spring-boot-starter-hutool + io.gitee.yunjiao-source.spring-boot + starter-id diff --git a/examples/example-hutool/src/main/java/io/yunjiao/example/hutool/HutoolCommandLineRunner.java b/examples/example-id/src/main/java/yunjiao/springboot/example/id/IdCommandLineRunner.java similarity index 82% rename from examples/example-hutool/src/main/java/io/yunjiao/example/hutool/HutoolCommandLineRunner.java rename to examples/example-id/src/main/java/yunjiao/springboot/example/id/IdCommandLineRunner.java index a05ee3911619a65fa6a10ee8fc8a81003750297a..cea4bcd9a1dccc0844744979fe04eb806b4e4c4d 100644 --- a/examples/example-hutool/src/main/java/io/yunjiao/example/hutool/HutoolCommandLineRunner.java +++ b/examples/example-id/src/main/java/yunjiao/springboot/example/id/IdCommandLineRunner.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.hutool; +package yunjiao.springboot.example.id; import cn.hutool.core.lang.Snowflake; import lombok.extern.slf4j.Slf4j; @@ -13,7 +13,7 @@ import org.springframework.stereotype.Component; */ @Slf4j @Component -public class HutoolCommandLineRunner implements CommandLineRunner { +public class IdCommandLineRunner implements CommandLineRunner { @Autowired private Snowflake snowflake; diff --git a/examples/example-hutool/src/main/java/io/yunjiao/example/hutool/HutoolExampleApplication.java b/examples/example-id/src/main/java/yunjiao/springboot/example/id/IdExampleApplication.java similarity index 63% rename from examples/example-hutool/src/main/java/io/yunjiao/example/hutool/HutoolExampleApplication.java rename to examples/example-id/src/main/java/yunjiao/springboot/example/id/IdExampleApplication.java index ae10978853f9f66ebd138bd643716efff6532d0b..293e27eba234ccbda28e2976a2e9c4d406e89667 100644 --- a/examples/example-hutool/src/main/java/io/yunjiao/example/hutool/HutoolExampleApplication.java +++ b/examples/example-id/src/main/java/yunjiao/springboot/example/id/IdExampleApplication.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.hutool; +package yunjiao.springboot.example.id; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -9,8 +9,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; * @author yangyunjiao */ @SpringBootApplication -public class HutoolExampleApplication { +public class IdExampleApplication { public static void main(String[] args) { - SpringApplication.run(HutoolExampleApplication.class, args); + SpringApplication.run(IdExampleApplication.class, args); } } diff --git a/examples/example-hutool/src/main/resources/application.yml b/examples/example-id/src/main/resources/application.yml similarity index 81% rename from examples/example-hutool/src/main/resources/application.yml rename to examples/example-id/src/main/resources/application.yml index 1b52d7587471654e03257c84b94ad4bb8ada9c58..4d7b1b28476ed63e07c6bdbc2caeb1114ee12216 100644 --- a/examples/example-hutool/src/main/resources/application.yml +++ b/examples/example-id/src/main/resources/application.yml @@ -6,5 +6,5 @@ logging: level: root: info org.springframework.boot.autoconfigure: info - io.yunjiao: debug + yunjiao.springboot: debug diff --git a/examples/example-querydsl-jpa/pom.xml b/examples/example-querydsl-jpa/pom.xml index ebae07cd0d12dc19501698f77aace1a4e844b7eb..b67e779a32e27792b2f243d257202a9eca6b3ecf 100644 --- a/examples/example-querydsl-jpa/pom.xml +++ b/examples/example-querydsl-jpa/pom.xml @@ -3,7 +3,7 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot examples ${revision} @@ -16,8 +16,8 @@ - io.gitee.yunjiao-source - spring-boot-starter-querydsl-jpa + io.gitee.yunjiao-source.spring-boot + starter-querydsl-jpa diff --git a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/QueryDSLJPAConfiguration.java b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLJPAConfiguration.java similarity index 82% rename from examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/QueryDSLJPAConfiguration.java rename to examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLJPAConfiguration.java index 7918e0f43cc56183432bdd2cfed81a185ad46f93..139037370c910333c24c41fcb150d2c6fd7c7034 100644 --- a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/QueryDSLJPAConfiguration.java +++ b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLJPAConfiguration.java @@ -1,6 +1,6 @@ -package io.yunjiao.example.querydsl; +package yunjiao.springboot.example.querydsl; -import io.yunjiao.springboot.autoconfigure.querydsl.jpa.JPAQueryFactoryConfigurer; +import yunjiao.springboot.autoconfigure.querydsl.jpa.JPAQueryFactoryConfigurer; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/QueryDSLJPAExampleApplication.java b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLJPAExampleApplication.java similarity index 89% rename from examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/QueryDSLJPAExampleApplication.java rename to examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLJPAExampleApplication.java index 9f0baead022e267f0f8e2700488ceec11c96e982..9954b2b6c1d32e9357fa3b9a8c94d73de0b3da91 100644 --- a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/QueryDSLJPAExampleApplication.java +++ b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLJPAExampleApplication.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.querydsl; +package yunjiao.springboot.example.querydsl; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/UserCommandLineRunner.java b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/UserCommandLineRunner.java similarity index 94% rename from examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/UserCommandLineRunner.java rename to examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/UserCommandLineRunner.java index 634d3295d11816f201f483ffe7d8198dab30fed2..135f6038c9a1460b5b233928cd804580ed8245ed 100644 --- a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/UserCommandLineRunner.java +++ b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/UserCommandLineRunner.java @@ -1,7 +1,7 @@ -package io.yunjiao.example.querydsl; +package yunjiao.springboot.example.querydsl; -import io.yunjiao.example.querydsl.jpa.User; -import io.yunjiao.example.querydsl.jpa.UserJPAService; +import yunjiao.springboot.example.querydsl.jpa.User; +import yunjiao.springboot.example.querydsl.jpa.UserJPAService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; diff --git a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/Order.java b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/Order.java similarity index 92% rename from examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/Order.java rename to examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/Order.java index f8aca97a4653d2046051c5927d799852b958e99a..d4b23fabe081e55ca431bbc89b3b90960868ae6f 100644 --- a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/Order.java +++ b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/Order.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.querydsl.jpa; +package yunjiao.springboot.example.querydsl.jpa; import jakarta.persistence.*; import lombok.Data; diff --git a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/User.java b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/User.java similarity index 94% rename from examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/User.java rename to examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/User.java index eac913f1176390c1fcece8373d6bc97f41ffdbde..42053503438cb68a1e3e9ca081e76d2a4b344405 100644 --- a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/User.java +++ b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/User.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.querydsl.jpa; +package yunjiao.springboot.example.querydsl.jpa; import jakarta.persistence.*; import lombok.Data; diff --git a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserJPARepository.java b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserJPARepository.java similarity index 85% rename from examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserJPARepository.java rename to examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserJPARepository.java index fa6099cc061293702935574654d843d3f426a694..0682b69ef377cfd624da8734bb64c57d3307c4f7 100644 --- a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserJPARepository.java +++ b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserJPARepository.java @@ -1,13 +1,11 @@ -package io.yunjiao.example.querydsl.jpa; +package yunjiao.springboot.example.querydsl.jpa; import com.querydsl.jpa.impl.JPADeleteClause; import com.querydsl.jpa.impl.JPAInsertClause; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAUpdateClause; -import io.yunjiao.extension.querydsl.QSpecification; -import io.yunjiao.extension.querydsl.jpa.JPAQueryRepositorySupport; -import jakarta.persistence.EntityManager; -import org.springframework.beans.factory.annotation.Autowired; +import yunjiao.springboot.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.jpa.JPAQueryRepositorySupport; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.querydsl.QPageRequest; @@ -19,8 +17,6 @@ import java.sql.Date; import java.util.List; import java.util.Optional; -import static io.yunjiao.example.querydsl.jpa.UserSpec.*; - /** * 仓库类 * @@ -32,10 +28,6 @@ public class UserJPARepository extends JPAQueryRepositorySupport { private static final QUser qUser = QUser.user; private static final QOrder qOrder = QOrder.order; - @Autowired - private EntityManager entityManager; - - public UserJPARepository() { super(qUser); } @@ -57,13 +49,13 @@ public class UserJPARepository extends JPAQueryRepositorySupport { // 使用名称查询唯一用户 public Optional findSingleByName(String name) { JPAQuery query = selectFrom(qUser); - return getCurdExecutor().findOnlyOne(query, nameEq(name)); + return getCurdExecutor().findOnlyOne(query, UserSpec.nameEq(name)); } // 多条件,排序查询 public List findList(String name, Integer age, Date birthDate) { JPAQuery query = selectFrom(qUser); - QSpecification spec = nameLike(name).and(ageGoe(age), birthDate(birthDate)); + QSpecification spec = UserSpec.nameLike(name).and(UserSpec.ageGoe(age), UserSpec.birthDate(birthDate)); QSort sort = QSort.by(qUser.age.asc(), qUser.birthDate.desc()); return getCurdExecutor().findList(query, spec, sort); } @@ -73,14 +65,14 @@ public class UserJPARepository extends JPAQueryRepositorySupport { JPAQuery countQuery = select(qUser.count()).from(qUser); JPAQuery query = selectFrom(qUser); QSort sort = QSort.by(qUser.age.desc()); - return getCurdExecutor().findPage(countQuery, query, QPageRequest.of(0, 5, sort), ageGoe(age)); + return getCurdExecutor().findPage(countQuery, query, QPageRequest.of(0, 5, sort), UserSpec.ageGoe(age)); } // 分页查询, 使用PageRequest对象 public Page findPage(Integer age) { JPAQuery query = selectFrom(qUser); QSort sort = QSort.by(qUser.age.asc()); - return findPage(query, PageRequest.of(0, 5, sort), ageGoe(age)); + return findPage(query, PageRequest.of(0, 5, sort), UserSpec.ageGoe(age)); } // 关联查询:查询已完成订单的用户信息 @@ -104,7 +96,7 @@ public class UserJPARepository extends JPAQueryRepositorySupport { public long updateName(Long id, String newName) { JPAUpdateClause update = update(qUser) .set(qUser.name, newName); - return getCurdExecutor().update(update, idEq(id)); + return getCurdExecutor().update(update, UserSpec.idEq(id)); } // 批量插入 @@ -127,7 +119,7 @@ public class UserJPARepository extends JPAQueryRepositorySupport { // 查询 JPAQuery queryClause = select(qUser.id).from(qUser).limit(maxLimit); - getCurdExecutor().applaySpecification(ageGoe(age), queryClause); + getCurdExecutor().applaySpecification(UserSpec.ageGoe(age), queryClause); while (true) { List userIdList = queryClause.fetch(); diff --git a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserJPAService.java b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserJPAService.java similarity index 95% rename from examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserJPAService.java rename to examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserJPAService.java index ea91cd24513c4821001b1e85b8ceffdc1ce7d5f9..d1364a3ee36fd40061addda9d99f5b2e28ef4278 100644 --- a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserJPAService.java +++ b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserJPAService.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.querydsl.jpa; +package yunjiao.springboot.example.querydsl.jpa; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserQuery.java b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserQuery.java similarity index 82% rename from examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserQuery.java rename to examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserQuery.java index c05dcfd2b6e9fc80659a18b02ca9564174df2a35..3435ab9daeef105e359959a0f7c4e437ec4b95c2 100644 --- a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserQuery.java +++ b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserQuery.java @@ -1,6 +1,6 @@ -package io.yunjiao.example.querydsl.jpa; +package yunjiao.springboot.example.querydsl.jpa; -import io.yunjiao.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.QSpecification; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; @@ -9,8 +9,8 @@ import org.springframework.util.StringUtils; import java.util.Objects; -import static io.yunjiao.example.querydsl.jpa.UserSpec.*; -import static io.yunjiao.extension.querydsl.QueryDSLUtils.orderBy; +import static yunjiao.springboot.example.querydsl.jpa.UserSpec.*; +import static yunjiao.springboot.extension.querydsl.QueryDSLUtils.orderBy; /** * 用户查询条件 diff --git a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserSpec.java b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserSpec.java similarity index 86% rename from examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserSpec.java rename to examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserSpec.java index 51135b7c9fcf61a0accfffd4255e55cf33de520f..d0296d6329ab8e1e90e05463ab8bf2f9a88742eb 100644 --- a/examples/example-querydsl-jpa/src/main/java/io/yunjiao/example/querydsl/jpa/UserSpec.java +++ b/examples/example-querydsl-jpa/src/main/java/yunjiao/springboot/example/querydsl/jpa/UserSpec.java @@ -1,6 +1,6 @@ -package io.yunjiao.example.querydsl.jpa; +package yunjiao.springboot.example.querydsl.jpa; -import io.yunjiao.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.QSpecification; import java.sql.Date; diff --git a/examples/example-querydsl-jpa/src/main/resources/application.yml b/examples/example-querydsl-jpa/src/main/resources/application.yml index 91718c47ea0004f3b2db8e411ef2b59b64a6c391..9c5515ae9e931805fd827a2bf4304cdc49235e25 100644 --- a/examples/example-querydsl-jpa/src/main/resources/application.yml +++ b/examples/example-querydsl-jpa/src/main/resources/application.yml @@ -12,6 +12,6 @@ logging: level: root: info org.springframework.boot.autoconfigure: info - io.yunjiao: debug + yunjiao.springboot: debug com.querydsl.jpa: debug # 打印SQL语句 diff --git a/examples/example-querydsl-sql/pom.xml b/examples/example-querydsl-sql/pom.xml index 6cf41be44d4323635b1603d0bb322b92d8edabb8..95c1070f1eaa95b19537555b7d23b1b548612aed 100644 --- a/examples/example-querydsl-sql/pom.xml +++ b/examples/example-querydsl-sql/pom.xml @@ -3,7 +3,7 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot examples ${revision} @@ -16,8 +16,8 @@ - io.gitee.yunjiao-source - spring-boot-starter-querydsl-sql + io.gitee.yunjiao-source.spring-boot + starter-querydsl-sql @@ -41,39 +41,44 @@ - - - - com.querydsl - querydsl-maven-plugin - - - - export - - - - - - com.mysql.cj.jdbc.Driver - jdbc:mysql://localhost:3306/yunjiao?userSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8 - system - system - io.yunjiao.example.querydsl - ${project.basedir}/target/generated-sources/java - - - - - com.mysql - mysql-connector-j - 9.2.0 - - - - - + + + querdsl-sql-export + + + + com.querydsl + querydsl-maven-plugin + + + + export + + + + + + com.mysql.cj.jdbc.Driver + jdbc:mysql://localhost:3306/yunjiao?userSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8 + system + system + io.yunjiao.example.querydsl + ${project.basedir}/target/generated-sources/java + + + + + com.mysql + mysql-connector-j + 9.2.0 + + + + + + + \ No newline at end of file diff --git a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/QueryDSLSQLConfiguration.java b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLSQLConfiguration.java similarity index 86% rename from examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/QueryDSLSQLConfiguration.java rename to examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLSQLConfiguration.java index 1d664d3e02c8d2f435071031643f485479b00d45..c60c60cf015161d3e1c14f568906bfc9d5eb5421 100644 --- a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/QueryDSLSQLConfiguration.java +++ b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLSQLConfiguration.java @@ -1,7 +1,7 @@ -package io.yunjiao.example.querydsl; +package yunjiao.springboot.example.querydsl; import com.querydsl.sql.SQLTemplates; -import io.yunjiao.springboot.autoconfigure.querydsl.sql.SQLQueryFactoryConfigurer; +import yunjiao.springboot.autoconfigure.querydsl.sql.SQLQueryFactoryConfigurer; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/QueryDSLSQLExampleApplication.java b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLSQLExampleApplication.java similarity index 89% rename from examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/QueryDSLSQLExampleApplication.java rename to examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLSQLExampleApplication.java index 4a776328c4e03027cf375ec48dd6a73d88f9786f..eb4ef517cc784da70c5cc358056491a66dbcaceb 100644 --- a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/QueryDSLSQLExampleApplication.java +++ b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/QueryDSLSQLExampleApplication.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.querydsl; +package yunjiao.springboot.example.querydsl; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/UserCommandLineRunner.java b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/UserCommandLineRunner.java similarity index 94% rename from examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/UserCommandLineRunner.java rename to examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/UserCommandLineRunner.java index cc1941475657714f66f2dc55a1c5cc8f6cc6bfa9..22855ac800c69f45938aede482559d899d4518d4 100644 --- a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/UserCommandLineRunner.java +++ b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/UserCommandLineRunner.java @@ -1,7 +1,7 @@ -package io.yunjiao.example.querydsl; +package yunjiao.springboot.example.querydsl; -import io.yunjiao.example.querydsl.sql.User; -import io.yunjiao.example.querydsl.sql.UserSQLService; +import yunjiao.springboot.example.querydsl.sql.User; +import yunjiao.springboot.example.querydsl.sql.UserSQLService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; diff --git a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/QOrders.java b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/QOrders.java similarity index 98% rename from examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/QOrders.java rename to examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/QOrders.java index f3c1ff6fa38134e8996f2bacb08fcd897c6aa676..ff222fd350049dd5b8a7b8f3b6aa40da4e578689 100644 --- a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/QOrders.java +++ b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/QOrders.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.querydsl.sql; +package yunjiao.springboot.example.querydsl.sql; import com.querydsl.core.types.Path; import com.querydsl.core.types.PathMetadata; diff --git a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/QUsers.java b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/QUsers.java similarity index 98% rename from examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/QUsers.java rename to examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/QUsers.java index 6c7c62d11819346ac29961cfdd0cc259e9d5f459..c72b5d50f8e1a33818021a30912def7c7e37c4f2 100644 --- a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/QUsers.java +++ b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/QUsers.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.querydsl.sql; +package yunjiao.springboot.example.querydsl.sql; import com.querydsl.core.types.Path; import com.querydsl.core.types.PathMetadata; diff --git a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/User.java b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/User.java similarity index 84% rename from examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/User.java rename to examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/User.java index c727ece1574cbeb842211e005a3ce79b52cd76f6..8fa7698f374579c184f514695bc87ffa0c6e25c1 100644 --- a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/User.java +++ b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/User.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.querydsl.sql; +package yunjiao.springboot.example.querydsl.sql; import lombok.Data; diff --git a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserPre.java b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserPre.java similarity index 86% rename from examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserPre.java rename to examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserPre.java index 41d4afd83c8033bf092bc144e050aae6c6a4de4b..0754c6e1f6a92b9a0cb02d70f4b7727499d592f7 100644 --- a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserPre.java +++ b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserPre.java @@ -1,7 +1,7 @@ -package io.yunjiao.example.querydsl.sql; +package yunjiao.springboot.example.querydsl.sql; import com.querydsl.core.types.Predicate; -import io.yunjiao.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.QSpecification; import java.sql.Date; diff --git a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserQuery.java b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserQuery.java similarity index 86% rename from examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserQuery.java rename to examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserQuery.java index 26c22c6ffee2e135f66f74b83c62415aa65a2a46..dedf036168ef32a42e519e2b5f2939d5dc998463 100644 --- a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserQuery.java +++ b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserQuery.java @@ -1,8 +1,8 @@ -package io.yunjiao.example.querydsl.sql; +package yunjiao.springboot.example.querydsl.sql; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Predicate; -import io.yunjiao.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.QSpecification; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; @@ -11,8 +11,8 @@ import org.springframework.util.StringUtils; import java.util.Objects; -import static io.yunjiao.example.querydsl.sql.UserSpec.*; -import static io.yunjiao.extension.querydsl.QueryDSLUtils.orderBy; +import static yunjiao.springboot.example.querydsl.sql.UserSpec.*; +import static yunjiao.springboot.extension.querydsl.QueryDSLUtils.orderBy; /** * 用户查询条件 diff --git a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserSQLRepository.java b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserSQLRepository.java similarity index 95% rename from examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserSQLRepository.java rename to examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserSQLRepository.java index 35a5fce530a100e02b9fa9cdd3293c73ad89e455..3b6f57b881a869b29b3e74cac070453928fc3c6a 100644 --- a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserSQLRepository.java +++ b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserSQLRepository.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.querydsl.sql; +package yunjiao.springboot.example.querydsl.sql; import com.google.common.collect.Lists; import com.querydsl.core.types.Projections; @@ -6,8 +6,8 @@ import com.querydsl.sql.SQLQuery; import com.querydsl.sql.dml.SQLDeleteClause; import com.querydsl.sql.dml.SQLInsertClause; import com.querydsl.sql.dml.SQLUpdateClause; -import io.yunjiao.extension.querydsl.QSpecification; -import io.yunjiao.extension.querydsl.sql.SQLQueryRepositorySupport; +import yunjiao.springboot.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.sql.SQLQueryRepositorySupport; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.querydsl.QPageRequest; @@ -19,7 +19,7 @@ import java.sql.Date; import java.util.List; import java.util.Optional; -import static io.yunjiao.example.querydsl.sql.UserSpec.*; +import static yunjiao.springboot.example.querydsl.sql.UserSpec.*; /** * 仓库类 diff --git a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserSQLService.java b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserSQLService.java similarity index 95% rename from examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserSQLService.java rename to examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserSQLService.java index 36ce3424fbe3655b4d6d055f339a7175a1f54775..f1fce6f91ac13ff833cb94f931b4e5489c136ddf 100644 --- a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserSQLService.java +++ b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserSQLService.java @@ -1,4 +1,4 @@ -package io.yunjiao.example.querydsl.sql; +package yunjiao.springboot.example.querydsl.sql; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserSpec.java b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserSpec.java similarity index 86% rename from examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserSpec.java rename to examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserSpec.java index 8a014a2b9c46ec8375053545b359caff0c7f8d2a..bdf12279aa8723b0f42753eabf5f89dcee7eb75d 100644 --- a/examples/example-querydsl-sql/src/main/java/io/yunjiao/example/querydsl/sql/UserSpec.java +++ b/examples/example-querydsl-sql/src/main/java/yunjiao/springboot/example/querydsl/sql/UserSpec.java @@ -1,6 +1,6 @@ -package io.yunjiao.example.querydsl.sql; +package yunjiao.springboot.example.querydsl.sql; -import io.yunjiao.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.QSpecification; import java.sql.Date; diff --git a/examples/example-querydsl-sql/src/main/resources/application.yml b/examples/example-querydsl-sql/src/main/resources/application.yml index ca9b06767aba8c5530b5236ed62bed025729b684..d7d4629dc341e56075f585a76f0bdae8b9976d9e 100644 --- a/examples/example-querydsl-sql/src/main/resources/application.yml +++ b/examples/example-querydsl-sql/src/main/resources/application.yml @@ -10,6 +10,6 @@ logging: level: root: info org.springframework.boot.autoconfigure: debug - io.yunjiao: debug + yunjiao.springboot: debug com.querydsl.sql: debug # 打印SQL语句 diff --git a/examples/pom.xml b/examples/pom.xml index adff1120813c380befb5e5db32a72a0a1ddba1d9..3f4aed37d38afa56f91dc11009ac2d2e184dc556 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -3,9 +3,9 @@ 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"> - io.gitee.yunjiao-source - spring-boot-starter-parent - 3.5.x.2 + io.gitee.yunjiao-source.spring-boot + starter-parent + 0.3.0 4.0.0 @@ -17,15 +17,16 @@ 示例项目 - example-hutool + example-id example-querydsl-sql example-querydsl-jpa example-apijson-fastjson2 example-apijson-gson + example-captcha - 3.5.x.2 + 0.3.0 1.5.0 diff --git a/extensions/README.md b/extensions/README.md new file mode 100644 index 0000000000000000000000000000000000000000..670bc0f2a2c2884c4aa7a5b542bccfde7630dac8 --- /dev/null +++ b/extensions/README.md @@ -0,0 +1,262 @@ +# extensions + +开源的框架扩展,使其有利于`Spring Boot`集成 + +## extension-apijson + +[APIJSON](http://apijson.cn/) 实现实时零代码接口和文档JSON 协议 与 ORM 库 + +如何使用请参考启动器[starter-apijson-fastjson2](../starters/starter-apijson-fastjson2) 与 [starter-apijson-gson](../starters/starter-apijson-gson) + +### IdKeyStrategy接口 + +主键名称策略接口,接口只有一个方法 +```java +String getIdKey(String database, String schema, String datasource, String table); +``` +用于获取主键名称。一般情况下,数据库表的主键名称是`id`,但很多不是这样的,如:`User`表的主键名是`user_id`, `Order`表 +的主键名称是`order_id`,这些都是很正常的,通用的名称。 + +在表主键名称不一样的情况下,需要实现此接口,根据`table`参数判断,返回该表的主键名称。 + +如果表的主键都是一样的,且名称都是`id`,那么你可以直接使用`IdKeyApijsonStrategy`实现类 + +### NewIdStrategy接口 + +主键值策略,接口只有一个方法 + +```java +Serializable newId(RequestMethod method, String database, String schema, String datasource, String table); +``` + +接口有多个实现类 +* NewIdUuidStrategy:uuid主键策略 +* NewIdTimestampStrategy:时间戳主键策略 +* NewIdSnowflakeStrategy:雪花算法主键策略 +* NewIdDatabaseStrategy:数据库主键策略,使用数据库功能生成主键 + + +## extension-id + +ID扩展,集成`Hutool`框架中`SnowFlake`类。 + +如何使用请参考启动器[starter-id](../starters/starter-id) + +## extension-querydsl + +[QueryDSL](http://querydsl.com/) 是一个框架,可以构建静态类型的 SQL 类查询。无需将查询编写为内联字符串或将它们外部化为 XML 文件, +它们可以通过 `Querydsl` 之类的流畅 API 构建。 + +如何使用请参考启动器[starter-querydsl-jpa](../starters/starter-querydsl-jpa) 与 [starter-querydsl-sql](../starters/starter-querydsl-sql) + +重要的扩展如下: +### QSpecification接口 + +仿`Spring`框架`Specification`接口,实现条件的组合 +```text +QSpecification spec = name().and(age()).and(email()); +"users.name = abc && users.age >= 18 && users.email = abc@qq.com" + +QSpecification spec = name().and(age()).andNot(email()); +"users.name = abc && users.age >= 18 && !(users.email = abc@qq.com)" + +QSpecification spec = name().andAnyOf(age(), email()); +"users.name = abc && (users.age >= 18 || users.email = abc@qq.com)" +``` +详细功能查看单元测试用例[QSpecificationTest](./extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/QSpecificationTest.java) + +### SQLQueryRepositorySupport抽象类 + +基于SQL的仓库支持,实现了对数据CURD操作,并且每个操作都添加了事务(Transactional)支持 + +* findOnlyOne:查询仅一条记录,如果有两条以上,抛出异常 +* findFirstOne:查询第一条记录 +* findMustOne:查询必须的一条记录,如果不存在记录,抛出异常 +* count:统计记录数 +* exist:是否存在记录 +* findList:列表查询,支持查询条件,排序 +* findTuple:指定字段列表查询,支持查询条件,排序 +* findPage:分页查询,支持查询条件,排序 +* update:更新操作 +* delete:删除操作 + +用户应该继承此类,便拥有以上的全部功能 + +```java + @Repository + static class DemoSQLQueryRepositorySupport extends SQLQueryRepositorySupport { + private final static QUsers user = QUsers.user; + private final static QOrders order = QOrders.order; + + // 主键查询 + public User findById(Long id) { + SQLQuery query = select(Projections.bean(User.class, user.all())) + .from(user) + .where(user.id.eq(id)); + return getCurdExecutor().findMustOne(query); + } + + // 多条件,排序查询 + public List findList(String name, Integer age, Date birthDate) { + SQLQuery query = select(Projections.bean(User.class, user.all())) + .from(user); + QSpecification spec = nameLike(name).and(ageGoe(age), birthDate(birthDate)); + QSort sort = QSort.by(user.age.asc(), user.birthDate.desc()); + return getCurdExecutor().findList(query, spec, sort); + } + + // 分页查询, 使用QPageRequest对象 + public Page findQPage(Integer age) { + SQLQuery query = select(Projections.bean(User.class, user.all())) + .from(user); + QSort sort = QSort.by(user.age.desc()); + return getCurdExecutor().findPage(query, QPageRequest.of(0, 5, sort), ageGoe(age)); + } + + // 分页查询, 使用PageRequest对象 + public Page findPage(Integer age) { + SQLQuery query = select(Projections.bean(User.class, user.all())) + .from(user); + QSort sort = QSort.by(user.age.asc()); + return findPage(query, PageRequest.of(0, 5, sort), ageGoe(age)); + } + + // 关联查询:查询已完成订单的用户信息 + public List findUserByOrderStatus() { + SQLQuery query = select(Projections.bean(User.class, user.all())) + .distinct() + .from(user) + .innerJoin(user.order, order) + .where(order.status.eq("completed")); + return getCurdExecutor().findList(query); + } + } +``` + +详细功能查看单元测试用例[SQLQueryRepositorySupportTest](./extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/SQLQueryRepositorySupportTest.java) + +### JPAQueryRepositorySupport抽象类 + +基于JPA的仓库支持,实现了对数据CURD操作,并且每个操作都添加了事务(Transactional)支持 +* findOnlyOne:查询仅一条记录,如果有两条以上,抛出异常 +* findFirstOne:查询第一条记录 +* findMustOne:查询必须的一条记录,如果不存在记录,抛出异常 +* count:统计记录数 +* exist:是否存在记录 +* findList:列表查询,支持查询条件,排序 +* findTuple:指定字段列表查询,支持查询条件,排序 +* findPage:分页查询,支持查询条件,排序 +* update:更新操作 +* delete:删除操作 + +用户应该继承此类,便拥有以上的全部功能 + +```java + @Repository + static class DemoJPAQueryRepositorySupport extends JPAQueryRepositorySupport { + // 主键查询 + public User findById(Long id) { + JPAQuery query = selectFrom(user) + .where(user.id.eq(id)); + return getCurdExecutor().findMustOne(query); + } + + // 多条件,排序查询 + public List findList(String name, Integer age, Date birthDate) { + JPAQuery query = selectFrom(user); + QSpecification spec = nameLike(name).and(ageGoe(age), birthDate(birthDate)); + QSort sort = QSort.by(user.age.asc(), user.birthDate.desc()); + return getCurdExecutor().findList(query, spec, sort); + } + + // 分页查询, 使用QPageRequest对象 + public Page findQPage(Integer age) { + JPAQuery query = selectFrom(user); + QSort sort = QSort.by(user.age.desc()); + return findPage(query, QPageRequest.of(0, 5, sort), ageGoe(age)); + } + + // 分页查询, 使用PageRequest对象 + public Page findPage(Integer age) { + JPAQuery query = selectFrom(user); + QSort sort = QSort.by(user.age.asc()); + return findPage(query, PageRequest.of(0, 5, sort), ageGoe(age)); + } + + // 关联查询:查询已完成订单的用户信息 + public List findUserByOrderStatus() { + JPAQuery query =selectFrom(user) + .distinct() + .innerJoin(user.orders, order) + .where(order.status.eq("completed")); + return getCurdExecutor().findList(query); + } + } +``` +详细功能查看单元测试用例[JPAQueryRepositorySupportTest](./extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/jpa/JPAQueryRepositorySupportTest.java) + +## extension-common + +通用工具扩展 + +### TimestampIdGenerator + +当前时间戳的ID生成器,`Long类型`,提供静态方法生成ID。线程安全的,仅用于测试或示例 + +```text + final int SIZE = 3000; + Set idSet = IntStream.range(0, SIZE).parallel().mapToLong(i -> TimestampIdGenerator.next()).boxed() + .collect(Collectors.toSet()); + System.out.println(idSet.stream().skip(SIZE -10).collect(Collectors.toList())); +``` + +输出: +```text +[1755402971097584, 1755402971097585, 1755402971097598, 1755402971097599, 1755402971097596, 1755402971097597, 1755402971097594, 1755402971097595, 1755402971097592, 1755402971097593] +``` + +### GaussianBlur + +高斯模糊算法,用于图片,可以设置模糊程度 + +### EnumCache + +枚举缓存,实现高效的枚举转换,如:名称转枚举,代码转枚举等 + +在定义枚举时 +```text +enum StatusEnum { + ...... + + static { + // 通过名称构建缓存,通过EnumCache.findByName(StatusEnum.class,"SUCCESS",null);调用能获取枚举 + EnumCache.registerByName(StatusEnum.class, StatusEnum.values()); + // 通过code构建缓存,通过EnumCache.findByValue(StatusEnum.class,"S",null);调用能获取枚举 + EnumCache.registerByValue(StatusEnum.class, StatusEnum.values(), StatusEnum::getCode); + } + } +``` + +### CaptchaService + +验证码服务接口,主要功能包括验证码生成,校验等 + +* CaptchaData draw() : 验证码生成 +* boolean verify(String originalCode, String userCode):验证码校验 +* CaptchaCategory getCategory():分类 + + + +## extension-captcha + +验证码扩展,集成Hutool-captcha框架 + +如何使用请参考启动器[starter-captcha](../starters/starter-captcha) + +集成Hutool框架验证码 +* CircleCaptchaService: 线段干扰的验证码 +* GifCaptchaService: 圆圈干扰验证码 +* LineCaptchaService: gif验证码 +* ShearCaptchaService: 扭曲干扰验证码 + + diff --git a/extensions/extension-apijson/pom.xml b/extensions/extension-apijson/pom.xml index 769fffb348cd1de24f1efd3b461fddd29cb2a676..943fda77e56675e2aeff27fda65fc4bbc798dc1b 100644 --- a/extensions/extension-apijson/pom.xml +++ b/extensions/extension-apijson/pom.xml @@ -3,7 +3,7 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extensions ${revision} @@ -16,7 +16,7 @@ - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extension-common diff --git a/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/_APIJSON.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/_APIJSON.java new file mode 100644 index 0000000000000000000000000000000000000000..ec490a4fc1b8bed1dc219515c2f3d2e70dee5766 --- /dev/null +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/_APIJSON.java @@ -0,0 +1,9 @@ +package yunjiao.springboot.extension.apjson; + +/** + * _APIJSON + * + * @author yangyunjiao + */ +public class _APIJSON { +} diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/annotation/ApijsonRest.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/annotation/ApijsonRest.java similarity index 87% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/annotation/ApijsonRest.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/annotation/ApijsonRest.java index 204b495aa75dfa30fa988047c0dbafda868b8533..067d032256ebabac7ea2bd74482726510b2d0f52 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/annotation/ApijsonRest.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/annotation/ApijsonRest.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.apjson.annotation; +package yunjiao.springboot.extension.apjson.annotation; import java.lang.annotation.Retention; import java.lang.annotation.Target; diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/GsonMap.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/GsonMap.java similarity index 97% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/GsonMap.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/GsonMap.java index 74567b04d6d4d8f93e2ef8b908d5bd34bbf016c9..f757c816382f1ddd1290e7765829194f8608b4c2 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/GsonMap.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/GsonMap.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.apjson.orm; +package yunjiao.springboot.extension.apjson.orm; import java.util.LinkedHashMap; import java.util.Map; diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/IdKeyApijsonStrategy.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/IdKeyApijsonStrategy.java similarity index 85% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/IdKeyApijsonStrategy.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/IdKeyApijsonStrategy.java index b0d5568ceaf75a9816eb40de48157aa02bcf4a8a..ab1bd44f9e55d57877f4348a467f6d317da5a0b8 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/IdKeyApijsonStrategy.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/IdKeyApijsonStrategy.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.apjson.orm; +package yunjiao.springboot.extension.apjson.orm; import apijson.JSONMap; diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/IdKeyStrategy.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/IdKeyStrategy.java similarity index 90% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/IdKeyStrategy.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/IdKeyStrategy.java index aa13c6b1827a8fd7ef7dfe3b0344e69de69a9202..79def433ad20904143d0ca2fce6aacf76659e507 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/IdKeyStrategy.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/IdKeyStrategy.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.apjson.orm; +package yunjiao.springboot.extension.apjson.orm; /** * 主键名称策略 diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdDatabaseStrategy.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdDatabaseStrategy.java similarity index 88% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdDatabaseStrategy.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdDatabaseStrategy.java index 667ad6c35d276b5250d5a434955ab6b458bdc3e6..985025a6bdfc9338daa56711b6f85c88f5cfd824 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdDatabaseStrategy.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdDatabaseStrategy.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.apjson.orm; +package yunjiao.springboot.extension.apjson.orm; import apijson.RequestMethod; diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdExceptionStrategy.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdExceptionStrategy.java similarity index 89% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdExceptionStrategy.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdExceptionStrategy.java index d0de90208fe117775c1dd4ac403799e1f9138918..4ce4df262ed6cf7b50d75c6a3b9bc397f925d004 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdExceptionStrategy.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdExceptionStrategy.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.apjson.orm; +package yunjiao.springboot.extension.apjson.orm; import apijson.RequestMethod; diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdSnowflakeStrategy.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdSnowflakeStrategy.java similarity index 91% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdSnowflakeStrategy.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdSnowflakeStrategy.java index dd21d74ff8fcbafc1ca17e265352391102119161..5b011b9211d7e7f86a8a3cf880fa2bb82280c16b 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdSnowflakeStrategy.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdSnowflakeStrategy.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.apjson.orm; +package yunjiao.springboot.extension.apjson.orm; import apijson.RequestMethod; import cn.hutool.core.lang.Snowflake; diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdStrategy.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdStrategy.java similarity index 92% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdStrategy.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdStrategy.java index 215b9ccd06adfb679e9bee77d002dec671833173..4624c3a4681b967b354224288d90e1bc952ff211 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdStrategy.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdStrategy.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.apjson.orm; +package yunjiao.springboot.extension.apjson.orm; import apijson.RequestMethod; diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdTimestampStrategy.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdTimestampStrategy.java similarity index 81% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdTimestampStrategy.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdTimestampStrategy.java index e7ef04da3d6ff389d312bd0ad081740a12a3ca71..56dda6c9cb2c0082edf6d17a7e3615daeb376e8f 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdTimestampStrategy.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdTimestampStrategy.java @@ -1,7 +1,7 @@ -package io.yunjiao.extension.apjson.orm; +package yunjiao.springboot.extension.apjson.orm; import apijson.RequestMethod; -import io.yunjiao.extension.common.generator.TimestampIdGenerator; +import yunjiao.springboot.extension.common.generator.TimestampIdGenerator; import java.io.Serializable; diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdUuidStrategy.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdUuidStrategy.java similarity index 89% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdUuidStrategy.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdUuidStrategy.java index 540675149b1fbe62a5766701c1e94a3ac74dbc65..745278932ce50a1822870e9c7ea911ee9010937d 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/NewIdUuidStrategy.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/NewIdUuidStrategy.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.apjson.orm; +package yunjiao.springboot.extension.apjson.orm; import apijson.RequestMethod; import cn.hutool.core.util.IdUtil; diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/SqlConnectProvider.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/SqlConnectProvider.java similarity index 96% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/SqlConnectProvider.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/SqlConnectProvider.java index 3607dacf8870b636c9e21ee16087dafcd9dafda2..eddfb428ced8123480dee780795b05e1fdcafdc0 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/orm/SqlConnectProvider.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/orm/SqlConnectProvider.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.apjson.orm; +package yunjiao.springboot.extension.apjson.orm; import apijson.NotNull; import org.slf4j.Logger; diff --git a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/util/ApijsonConsts.java b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/util/ApijsonConsts.java similarity index 93% rename from extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/util/ApijsonConsts.java rename to extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/util/ApijsonConsts.java index c3438fb3fc37061ad4d16453c6d60cf2dc623704..0057b60bf93c1616b6c1f4d6ca55a4b30297c53d 100644 --- a/extensions/extension-apijson/src/main/java/io/yunjiao/extension/apjson/util/ApijsonConsts.java +++ b/extensions/extension-apijson/src/main/java/yunjiao/springboot/extension/apjson/util/ApijsonConsts.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.apjson.util; +package yunjiao.springboot.extension.apjson.util; import apijson.orm.SQLConfig; diff --git a/extensions/extension-captcha/pom.xml b/extensions/extension-captcha/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..66916ba7306e9ea6b417c706642f55641f610b90 --- /dev/null +++ b/extensions/extension-captcha/pom.xml @@ -0,0 +1,32 @@ + + + + io.gitee.yunjiao-source.spring-boot + extensions + ${revision} + + 4.0.0 + + extension-captcha + jar + Extension :: Captcha + 验证码扩展,集成Hutool,aj-captcha + + + + io.gitee.yunjiao-source.spring-boot + extension-common + + + cn.hutool + hutool-captcha + + + com.anji-plus + captcha + + + + \ No newline at end of file diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/CaptchaException.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/CaptchaException.java new file mode 100644 index 0000000000000000000000000000000000000000..6569cfce8b89531ae15940ab281b6b06f3d6a576 --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/CaptchaException.java @@ -0,0 +1,19 @@ +package yunjiao.springboot.extension.captcha; + +import yunjiao.springboot.extension.common.util.CommonRuntimeException; + +/** + * 验证码异常 + * + * @author yangyunjiao + */ +public class CaptchaException extends CommonRuntimeException { + + public CaptchaException(String message) { + super(message); + } + + public CaptchaException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/_Captcha.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/_Captcha.java new file mode 100644 index 0000000000000000000000000000000000000000..a2c389facd0391212eae10f984e0dd94db953ac0 --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/_Captcha.java @@ -0,0 +1,9 @@ +package yunjiao.springboot.extension.captcha; + +/** + * _Captcha + * + * @author yangyunjiao + */ +public class _Captcha { +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/BaseCaptchaService.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/BaseCaptchaService.java new file mode 100644 index 0000000000000000000000000000000000000000..a11672eecff7b18f81b160267e4497da9f77ed31 --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/BaseCaptchaService.java @@ -0,0 +1,61 @@ +package yunjiao.springboot.extension.captcha.anji; + +import com.anji.captcha.model.common.CaptchaTypeEnum; +import com.anji.captcha.model.common.ResponseModel; +import com.anji.captcha.model.vo.CaptchaVO; +import com.anji.captcha.service.CaptchaCacheService; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.util.StringUtils; +import yunjiao.springboot.extension.captcha.CaptchaException; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.captcha.CaptchaService; + +/** + * 抽象的验证码 + * + * @author yangyunjiao + */ +@Getter +@RequiredArgsConstructor +public abstract class BaseCaptchaService implements CaptchaService { + protected static final String CACHE_TYPE = "local"; + + protected static final String REDIS_CAPTCHA_KEY = "RUNNING:CAPTCHA:%s"; + + private final com.anji.captcha.service.CaptchaService captchaService; + + private final CaptchaCacheService captchaCacheService; + + protected abstract CaptchaTypeEnum getCaptchaType(); + + protected abstract CaptchaData convert(CaptchaData data, CaptchaVO vo); + + protected boolean between(int target, int start, int end) { + return start <= target && target <= end; + } + + @Override + public CaptchaData draw() { + // 准备参数 + CaptchaVO vo = new CaptchaVO(); + vo.setCaptchaType(getCaptchaType().getCodeValue()); + + // 生成验证码 + ResponseModel model = captchaService.get(vo); + if (!model.isSuccess()) { + throw new CaptchaException(model.getRepMsg()); + } + + CaptchaVO captcha = (CaptchaVO)model.getRepData(); + String token = captcha.getToken(); + String codeKey = String.format(REDIS_CAPTCHA_KEY, token); + + String code = captchaCacheService.get(codeKey); + if (StringUtils.hasText(code)) { + captchaCacheService.delete(codeKey); + } + + return convert(new CaptchaData().key(token).code(code).category(getCategory()), captcha); + } +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/BlockPuzzleCaptchaService.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/BlockPuzzleCaptchaService.java new file mode 100644 index 0000000000000000000000000000000000000000..04545c54ac21359f41b01a3270dab5a05163f5ad --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/BlockPuzzleCaptchaService.java @@ -0,0 +1,55 @@ +package yunjiao.springboot.extension.captcha.anji; + +import com.anji.captcha.model.common.CaptchaTypeEnum; +import com.anji.captcha.model.vo.CaptchaVO; +import com.anji.captcha.service.CaptchaCacheService; +import com.anji.captcha.service.CaptchaService; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.captcha.Point; +import yunjiao.springboot.extension.common.util.GsonUtils; + +import java.util.Base64; + +/** + * 滑动验证码 服务 + * + * @author yangyunjiao + */ +public class BlockPuzzleCaptchaService extends BaseCaptchaService { + private final Integer slipOffset; + + public BlockPuzzleCaptchaService(CaptchaService captchaService, CaptchaCacheService captchaCacheService, Integer slipOffset) { + super(captchaService, captchaCacheService); + this.slipOffset = slipOffset; + } + + + @Override + public boolean verify(String originalCode, String userCode) { + Point original = GsonUtils.fromJson(originalCode, Point.class); + Point user = GsonUtils.fromJson(userCode, Point.class); + + return between(user.x(), original.x() - slipOffset, original.x() + slipOffset) + && between(user.y(), original.y() - slipOffset, original.y() + slipOffset); + } + + @Override + public CaptchaCategory getCategory() { + return CaptchaCategory.blockPuzzle; + } + + @Override + protected CaptchaTypeEnum getCaptchaType() { + return CaptchaTypeEnum.BLOCKPUZZLE; + } + + @Override + protected CaptchaData convert(CaptchaData data, CaptchaVO vo) { + String backgroundImageBase64 = vo.getOriginalImageBase64(); + String captchaImageBase64 = vo.getJigsawImageBase64(); + + return data.backgroundImage(Base64.getDecoder().decode(backgroundImageBase64)) + .captchaImage(Base64.getDecoder().decode(captchaImageBase64)); + } +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/ClickWorkCaptchaService.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/ClickWorkCaptchaService.java new file mode 100644 index 0000000000000000000000000000000000000000..da8b9605f0e46eef083d30dce0ec3be7fc60bfa7 --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/ClickWorkCaptchaService.java @@ -0,0 +1,65 @@ +package yunjiao.springboot.extension.captcha.anji; + +import com.anji.captcha.model.common.CaptchaTypeEnum; +import com.anji.captcha.model.vo.CaptchaVO; +import com.anji.captcha.service.CaptchaCacheService; +import com.anji.captcha.service.CaptchaService; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.captcha.Point; +import yunjiao.springboot.extension.common.util.GsonUtils; + +import java.util.Base64; +import java.util.List; + +/** + * 滑块拼图验证码 服务 + * + * @author yangyunjiao + */ +public class ClickWorkCaptchaService extends BaseCaptchaService { + private final Integer slipOffset; + + public ClickWorkCaptchaService(CaptchaService captchaService, CaptchaCacheService captchaCacheService, Integer slipOffset) { + super(captchaService, captchaCacheService); + this.slipOffset = slipOffset; + } + + + @Override + public boolean verify(String originalCode, String userCode) { + List originalList = GsonUtils.toList(originalCode, Point.class); + List userList = GsonUtils.toList(userCode, Point.class); + if (originalList.size() != userList.size()) { + return false; + } + + for (int i = 0; i < originalList.size(); i++) { + Point original = originalList.get(i); + Point user = userList.get(i); + boolean passed = between(user.x(), original.x() - slipOffset, original.x() + slipOffset) + && between(user.y(), original.y() - slipOffset, original.y() + slipOffset); + if (!passed) { + return false; + } + } + return true; + } + + @Override + public CaptchaCategory getCategory() { + return CaptchaCategory.clickWord; + } + + @Override + protected CaptchaTypeEnum getCaptchaType() { + return CaptchaTypeEnum.CLICKWORD; + } + + @Override + protected CaptchaData convert(CaptchaData data, CaptchaVO vo) { + String captchaImageBase64 = vo.getOriginalImageBase64(); + + return data.captchaImage(Base64.getDecoder().decode(captchaImageBase64)); + } +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/RotatePluzzleCaptchaService.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/RotatePluzzleCaptchaService.java new file mode 100644 index 0000000000000000000000000000000000000000..54686c001bf1e1c3c0e66266511a995b7f90c4a2 --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/anji/RotatePluzzleCaptchaService.java @@ -0,0 +1,44 @@ +package yunjiao.springboot.extension.captcha.anji; + +import com.anji.captcha.model.common.CaptchaTypeEnum; +import com.anji.captcha.model.vo.CaptchaVO; +import com.anji.captcha.service.CaptchaCacheService; +import com.anji.captcha.service.CaptchaService; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; + +import java.util.Base64; + +/** + * 旋转拼图验证码 服务 + * + * @author yangyunjiao + */ +public class RotatePluzzleCaptchaService extends BaseCaptchaService { + + public RotatePluzzleCaptchaService(CaptchaService captchaService, CaptchaCacheService captchaCacheService) { + super(captchaService, captchaCacheService); + } + + @Override + public boolean verify(String originalCode, String userCode) { + return false; + } + + @Override + public CaptchaCategory getCategory() { + return CaptchaCategory.rotatePuzzle; + } + + @Override + protected CaptchaTypeEnum getCaptchaType() { + return CaptchaTypeEnum.ROTATEPUZZLE; + } + + @Override + protected CaptchaData convert(CaptchaData data, CaptchaVO vo) { + String captchaImageBase64 = vo.getOriginalImageBase64(); + + return data.captchaImage(Base64.getDecoder().decode(captchaImageBase64)); + } +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/AbstractCaptchaBuilder.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/AbstractCaptchaBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..55dbeb4ae5462277a3498838696826f3db0b0481 --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/AbstractCaptchaBuilder.java @@ -0,0 +1,95 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import cn.hutool.captcha.AbstractCaptcha; +import cn.hutool.captcha.generator.CodeGenerator; +import yunjiao.springboot.extension.common.model.ColorType; +import lombok.Getter; +import lombok.Setter; + +import java.awt.*; + +/** + * 抽象的验证码创建者 + * + * @author yangyunjiao + */ +@Getter +@Setter +public abstract class AbstractCaptchaBuilder { + /** + * 图片的宽度 + */ + private Integer width; + + /** + * 图片的高度 + */ + private Integer height; + + /** + * 验证码干扰元素个数(干扰线宽度) + */ + private Integer interfereCount; + + /** + * 背景色 + */ + private ColorType backgroundColor; + + /** + * 文字透明度,取值0~1,1表示不透明 + */ + private Float transparency; + + /** + * 模糊度(0 - 30) + */ + private Integer fuzziness; + + /** + * 字体 + */ + private Font font; + + /** + * 码生成器 + */ + private CodeGenerator generator; + + /** + * 校验时是否忽略大小写 + */ + private Boolean validIgnoreCase; + + /** + * 创建验证码工具,子类实现 + * + * @return 实例 + */ + protected abstract C createCaptcha(); + + /** + * 填充验证码工具 + * @param captcha 必须值 + */ + protected void fill(AbstractCaptcha captcha) { + captcha.setFont(font); + captcha.setBackground(backgroundColor.getMapping()); + + if (transparency != null) { + captcha.setTextAlpha(transparency); + } + } + + /** + * 创建验证码工具 + * + * @return 实例 + */ + public C build() { + C captcha = createCaptcha(); + fill(captcha); + return captcha; + } + +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/AbstractCaptchaService.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/AbstractCaptchaService.java new file mode 100644 index 0000000000000000000000000000000000000000..5fe41d3722c36513ed8f745a66d9218c6c8d3add --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/AbstractCaptchaService.java @@ -0,0 +1,68 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import cn.hutool.core.img.ImgUtil; +import cn.hutool.core.util.IdUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.StringUtils; +import yunjiao.springboot.extension.captcha.CaptchaException; +import yunjiao.springboot.extension.common.algorithm.GaussianBlur; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.captcha.CaptchaService; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * 抽象的验证码 服务 + * + * @author yangyunjiao + */ +@Slf4j +public abstract class AbstractCaptchaService implements CaptchaService { + + /** + * 获取 校验时是否忽略大小写 + * @return 校验时是否忽略大小写 + */ + protected abstract Boolean getValidIgnoreCase(); + + protected abstract Integer getFuzziness(); + + protected BufferedImage handleFuzziness(BufferedImage image) { + Integer fuzziness = getFuzziness(); + if (fuzziness != null && fuzziness > 0) { + return GaussianBlur.execute(image, fuzziness); + } + return image; + } + + protected CaptchaData createCaptchaData(String code, BufferedImage image) { + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + ImgUtil.writePng(image, out); + byte[] imageBytes = out.toByteArray(); + + return new CaptchaData() + .key(IdUtil.fastSimpleUUID()) + .code(code) + .category(getCategory()) + .captchaImage(imageBytes); + } catch (IOException e) { + throw new CaptchaException("生成验证码图片异常", e); + } + } + + @Override + public boolean verify(String originalCode, String userCode) { + if(StringUtils.hasText(originalCode) && StringUtils.hasText(userCode)) { + Boolean ignoreCase = getValidIgnoreCase(); + if (Boolean.TRUE.equals(ignoreCase)) { + return originalCode.equalsIgnoreCase(userCode); + } else { + return originalCode.equals(userCode); + } + } + + return false; + } +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/CircleCaptchaBuilder.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/CircleCaptchaBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..8ce6b74ad3627e6b5a43479c5d680080fa6f04ee --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/CircleCaptchaBuilder.java @@ -0,0 +1,16 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import cn.hutool.captcha.CircleCaptcha; + +/** + * 圆圈干扰验证码 创建器 + * + * @author yangyunjiao + */ +public class CircleCaptchaBuilder extends AbstractCaptchaBuilder { + + @Override + protected CircleCaptcha createCaptcha() { + return new CircleCaptcha(getWidth(), getHeight(), getGenerator(), getInterfereCount()); + } +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/CircleCaptchaService.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/CircleCaptchaService.java new file mode 100644 index 0000000000000000000000000000000000000000..9201e1b721e43c9e36514bbc1eaa6b2f9f8a6e6a --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/CircleCaptchaService.java @@ -0,0 +1,49 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import cn.hutool.captcha.CircleCaptcha; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import lombok.RequiredArgsConstructor; + +import java.awt.image.BufferedImage; + +/** + * 圆圈干扰验证码 服务 + * + * @author yangyunjiao + */ +@RequiredArgsConstructor +public class CircleCaptchaService extends AbstractCaptchaService { + /** + * 创建器 + */ + private final CircleCaptchaBuilder builder; + + @Override + public CaptchaData draw() { + CircleCaptcha captcha = builder.build(); + // 生成码 + String code = captcha.getGenerator().generate(); + // 生成图片 + BufferedImage image = (BufferedImage)captcha.createImage(code); + + image = handleFuzziness(image); + return createCaptchaData(code, image); + } + + @Override + public CaptchaCategory getCategory() { + return CaptchaCategory.circle; + } + + @Override + protected Boolean getValidIgnoreCase() { + return builder.getValidIgnoreCase(); + } + + @Override + protected Integer getFuzziness() { + return builder.getFuzziness(); + } + +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/CodeGeneratorType.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/CodeGeneratorType.java new file mode 100644 index 0000000000000000000000000000000000000000..d78f24f2a91bcd3d431c747250778e661a1c1767 --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/CodeGeneratorType.java @@ -0,0 +1,92 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import cn.hutool.captcha.generator.CodeGenerator; +import cn.hutool.captcha.generator.MathGenerator; +import cn.hutool.captcha.generator.RandomGenerator; +import cn.hutool.core.util.RandomUtil; + +import java.util.function.Function; + +/** + * 验证码生成类型。实现{@link Function}接口,创建验证码生成器 + * + * @author yangyunjiao + */ +public enum CodeGeneratorType implements Function { + /** + * 算术验证码,如 2 + 3 = ? + */ + math { + @Override + public CodeGenerator apply(Integer length) { + return new MathGenerator(length); + } + }, + + /** + * 数字+大小写字母 验证码 + */ + numAndChar { + @Override + public CodeGenerator apply(Integer length) { + return new RandomGenerator(length); + } + }, + + /** + * 数字+大写字母 验证码 + */ + numAndUpperChar { + @Override + public CodeGenerator apply(Integer length) { + return new RandomGenerator(RandomUtil.BASE_NUMBER + RandomUtil.BASE_CHAR.toUpperCase(), length); + } + }, + + /** + * 数字+小写字母 验证码 + */ + numAndLowerChar { + @Override + public CodeGenerator apply(Integer length) { + return new RandomGenerator(RandomUtil.BASE_CHAR_NUMBER_LOWER, length); + } + }, + + /** + * 数字 验证码 + */ + num { + @Override + public CodeGenerator apply(Integer length) { + return new RandomGenerator(RandomUtil.BASE_NUMBER, length); + } + }, + + /** + * 大写字母 验证码 + */ + upperChar { + @Override + public CodeGenerator apply(Integer length) { + return new RandomGenerator(RandomUtil.BASE_CHAR.toUpperCase(), length); + } + }, + + /** + * 小写写字母 验证码 + */ + lowerChar { + @Override + public CodeGenerator apply(Integer length) { + return new RandomGenerator(RandomUtil.BASE_CHAR, length); + } + }, + + upperAndLowerChar { + @Override + public CodeGenerator apply(Integer length) { + return new RandomGenerator(RandomUtil.BASE_CHAR + RandomUtil.BASE_CHAR.toUpperCase(), length); + } + } +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/GifCaptchaBuilder.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/GifCaptchaBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..7a9cc060c4484a30499c6fe700c6d44681d1bab8 --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/GifCaptchaBuilder.java @@ -0,0 +1,44 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import cn.hutool.captcha.GifCaptcha; +import lombok.Getter; +import lombok.Setter; + +/** + * Gif验证码 创建器 + * + * @author yangyunjiao + */ +@Getter +@Setter +public class GifCaptchaBuilder extends AbstractCaptchaBuilder { + /** + * 量化器取样间隔, 1 ~ 20 值之间 - 默认是10ms + */ + private Integer quality; + + /** + * 帧循环次数,默认是 0, 意味着无限循环 + */ + private Integer repeat; + + /** + * 设置随机颜色时,最小的取色范围 + */ + private Integer minColor; + + /** + * 设置随机颜色时,最大的取色范围 + */ + private Integer maxColor; + + @Override + protected GifCaptcha createCaptcha() { + GifCaptcha gifCaptcha = new GifCaptcha(getWidth(), getHeight(), getGenerator(), getInterfereCount()); + gifCaptcha.setQuality(quality); + gifCaptcha.setRepeat(repeat); + gifCaptcha.setMaxColor(maxColor); + gifCaptcha.setMinColor(minColor); + return gifCaptcha; + } +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/GifCaptchaService.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/GifCaptchaService.java new file mode 100644 index 0000000000000000000000000000000000000000..46400c75ec1316c6ba59681d5ccb6e08f57e7264 --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/GifCaptchaService.java @@ -0,0 +1,47 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import cn.hutool.captcha.GifCaptcha; +import cn.hutool.core.util.IdUtil; +import lombok.RequiredArgsConstructor; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; + +/** + * gif验证码 服务 + * + * @author yangyunjiao + */ +@RequiredArgsConstructor +public class GifCaptchaService extends AbstractCaptchaService { + /** + * 创建器 + */ + private final GifCaptchaBuilder builder; + + @Override + public CaptchaData draw() { + GifCaptcha captcha = builder.build(); + String code = captcha.getCode(); + return new CaptchaData() + .key(IdUtil.fastSimpleUUID()) + .code(code) + .category(getCategory()) + .captchaImage(captcha.getImageBytes()); + } + + @Override + public CaptchaCategory getCategory() { + return CaptchaCategory.gif; + } + + @Override + protected Boolean getValidIgnoreCase() { + return builder.getValidIgnoreCase(); + } + + @Override + protected Integer getFuzziness() { + return builder.getFuzziness(); + } + +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/LineCaptchaBuilder.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/LineCaptchaBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..e09d3d3ab63ed447fc98ca67069ad0f4ba5eb18a --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/LineCaptchaBuilder.java @@ -0,0 +1,15 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import cn.hutool.captcha.LineCaptcha; + +/** + * 线段干扰的验证码 创建器 + * + * @author yangyunjiao + */ +public class LineCaptchaBuilder extends AbstractCaptchaBuilder { + @Override + protected LineCaptcha createCaptcha() { + return new LineCaptcha(getWidth(), getHeight(), getGenerator(), getInterfereCount()); + } +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/LineCaptchaService.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/LineCaptchaService.java new file mode 100644 index 0000000000000000000000000000000000000000..6349cfab161469d7990fd4898350a42bfc0192f5 --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/LineCaptchaService.java @@ -0,0 +1,49 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import cn.hutool.captcha.LineCaptcha; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import lombok.RequiredArgsConstructor; + +import java.awt.image.BufferedImage; + +/** + * 线段干扰的验证码 服务 + * + * @author yangyunjiao + */ +@RequiredArgsConstructor +public class LineCaptchaService extends AbstractCaptchaService { + /** + * 创建器 + */ + private final LineCaptchaBuilder builder; + + @Override + public CaptchaData draw() { + LineCaptcha captcha = builder.build(); + // 生成码 + String code = captcha.getGenerator().generate(); + // 生成图片 + BufferedImage image = (BufferedImage)captcha.createImage(code); + + image = handleFuzziness(image); + return createCaptchaData(code, image); + } + + @Override + public CaptchaCategory getCategory() { + return CaptchaCategory.line; + } + + @Override + protected Boolean getValidIgnoreCase() { + return builder.getValidIgnoreCase(); + } + + @Override + protected Integer getFuzziness() { + return builder.getFuzziness(); + } + +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/ShearCaptchaBuilder.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/ShearCaptchaBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..b84942c6199ded61a6dcdf44cc0ff6a3e2ba2f5f --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/ShearCaptchaBuilder.java @@ -0,0 +1,15 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import cn.hutool.captcha.ShearCaptcha; + +/** + * 扭曲干扰验证码 创建器 + * + * @author yangyunjiao + */ +public class ShearCaptchaBuilder extends AbstractCaptchaBuilder { + @Override + protected ShearCaptcha createCaptcha() { + return new ShearCaptcha(getWidth(), getHeight(), getGenerator(), getInterfereCount()); + } +} diff --git a/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/ShearCaptchaService.java b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/ShearCaptchaService.java new file mode 100644 index 0000000000000000000000000000000000000000..65841ce3eedaf1c1588a6a730ca1f0aebce90660 --- /dev/null +++ b/extensions/extension-captcha/src/main/java/yunjiao/springboot/extension/captcha/hutool/ShearCaptchaService.java @@ -0,0 +1,49 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import cn.hutool.captcha.ShearCaptcha; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import lombok.RequiredArgsConstructor; + +import java.awt.image.BufferedImage; + +/** + * 扭曲干扰验证码 服务 + * + * @author yangyunjiao + */ +@RequiredArgsConstructor +public class ShearCaptchaService extends AbstractCaptchaService { + /** + * 创建器 + */ + private final ShearCaptchaBuilder builder; + + @Override + public CaptchaData draw() { + ShearCaptcha captcha = builder.build(); + // 生成码 + String code = captcha.getGenerator().generate(); + // 生成图片 + BufferedImage image = (BufferedImage)captcha.createImage(code); + + image = handleFuzziness(image); + return createCaptchaData(code, image); + } + + @Override + public CaptchaCategory getCategory() { + return CaptchaCategory.shear; + } + + @Override + protected Boolean getValidIgnoreCase() { + return builder.getValidIgnoreCase(); + } + + @Override + protected Integer getFuzziness() { + return builder.getFuzziness(); + } + +} diff --git a/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/CaptchaJFrameDemo.java b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/CaptchaJFrameDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..ed75a5e831dc1381d3e9ad77785e5f95f24da1aa --- /dev/null +++ b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/CaptchaJFrameDemo.java @@ -0,0 +1,219 @@ +package yunjiao.springboot.extension.captcha; + +import cn.hutool.captcha.CaptchaUtil; +import cn.hutool.captcha.LineCaptcha; +import com.anji.captcha.model.common.Const; +import com.anji.captcha.service.CaptchaCacheService; +import com.anji.captcha.service.CaptchaService; +import com.anji.captcha.service.impl.CaptchaServiceFactory; +import yunjiao.springboot.extension.captcha.anji.BlockPuzzleCaptchaService; +import yunjiao.springboot.extension.captcha.anji.ClickWorkCaptchaService; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.model.ColorType; +import yunjiao.springboot.extension.captcha.hutool.*; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Properties; + +/** + * 可视化界面 + * + * @author yangyunjiao + */ +public class CaptchaJFrameDemo extends JFrame { + private JPanel captchaPanel; + + private JButton generateButton; + + private LineCaptchaService lineCaptchaService; + + private CircleCaptchaService circleCaptchaService; + + private ShearCaptchaService shearCaptchaService; + + private GifCaptchaService gifCaptchaService; + + private BlockPuzzleCaptchaService blockPuzzleCaptchaService; + + private ClickWorkCaptchaService clickWorkCaptchaService; + + public CaptchaJFrameDemo() { + setTitle("验证码生成器"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(800, 800); + setLocationRelativeTo(null); + + initUI(); + initService(); + + // 初始生成验证码 + generateCaptchas(); + } + + private void initService() { + Font font = new Font(null, Font.PLAIN, 36); + LineCaptchaBuilder lcb = new LineCaptchaBuilder(); + lcb.setWidth(250); + lcb.setHeight(50); + lcb.setInterfereCount(60); + lcb.setBackgroundColor(ColorType.white); + lcb.setFuzziness(2); + lcb.setValidIgnoreCase(true); + lcb.setFont(font); + lcb.setGenerator(CodeGeneratorType.numAndChar.apply(5)); + lineCaptchaService = new LineCaptchaService(lcb); + + CircleCaptchaBuilder ccb = new CircleCaptchaBuilder(); + ccb.setWidth(250); + ccb.setHeight(50); + ccb.setInterfereCount(30); + ccb.setBackgroundColor(ColorType.white); + ccb.setFuzziness(2); + ccb.setValidIgnoreCase(true); + ccb.setFont(font); + ccb.setGenerator(CodeGeneratorType.numAndChar.apply(5)); + circleCaptchaService = new CircleCaptchaService(ccb); + + ShearCaptchaBuilder scb = new ShearCaptchaBuilder(); + scb.setWidth(250); + scb.setHeight(50); + scb.setInterfereCount(4); + scb.setBackgroundColor(ColorType.white); + scb.setFuzziness(2); + scb.setValidIgnoreCase(true); + scb.setFont(font); + scb.setGenerator(CodeGeneratorType.numAndChar.apply(5)); + + shearCaptchaService = new ShearCaptchaService(scb); + + GifCaptchaBuilder gcb = new GifCaptchaBuilder(); + gcb.setWidth(250); + gcb.setHeight(50); + gcb.setInterfereCount(10); + gcb.setBackgroundColor(ColorType.white); + gcb.setFuzziness(2); + gcb.setValidIgnoreCase(true); + gcb.setFont(font); + gcb.setGenerator(CodeGeneratorType.numAndChar.apply(5)); + gcb.setQuality(10); + gcb.setRepeat(0); + gcb.setMinColor(0); + gcb.setMaxColor(255); + + gifCaptchaService = new GifCaptchaService(gcb); + + Properties config = new Properties(); + config.put(Const.CAPTCHA_CACHETYPE, "local"); + config.put(Const.CAPTCHA_WATER_MARK, "我的水印"); + config.put(Const.CAPTCHA_FONT_TYPE, "WenQuanZhengHei.ttf"); + config.put(Const.CAPTCHA_TYPE, "default"); + config.put(Const.CAPTCHA_INTERFERENCE_OPTIONS, "0"); + config.put(Const.ORIGINAL_PATH_JIGSAW, ""); + config.put(Const.ORIGINAL_PATH_PIC_CLICK, ""); + config.put(Const.CAPTCHA_SLIP_OFFSET, "5"); + config.put(Const.CAPTCHA_AES_STATUS, "false"); + config.put(Const.CAPTCHA_WATER_FONT, "WenQuanZhengHei.ttf"); + // CacheUtil的定时任务存在泄露的问题 + config.put(Const.CAPTCHA_TIMING_CLEAR_SECOND, "0"); + + config.put(Const.CAPTCHA_FONT_SIZE, "25"); + config.put(Const.CAPTCHA_FONT_STYLE, Font.BOLD); + config.put(Const.CAPTCHA_WORD_COUNT, "4"); + + CaptchaService captchaService = CaptchaServiceFactory.getInstance(config); + CaptchaCacheService captchaCacheService = CaptchaServiceFactory.getCache("local"); + blockPuzzleCaptchaService = new BlockPuzzleCaptchaService(captchaService, + captchaCacheService, + 5); + clickWorkCaptchaService = new ClickWorkCaptchaService(captchaService, + captchaCacheService, + 5); + } + + private void initUI() { + setLayout(new BorderLayout()); + + // 创建验证码显示面板 + captchaPanel = new JPanel(new GridLayout(3, 3, 10, 10)); + captchaPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + add(captchaPanel, BorderLayout.CENTER); + + // 创建按钮面板 + JPanel buttonPanel = new JPanel(); + generateButton = new JButton("生成验证码"); + generateButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 16)); + generateButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + generateCaptchas(); + } + }); + buttonPanel.add(generateButton); + add(buttonPanel, BorderLayout.SOUTH); + } + + private void generateCaptchas() { + captchaPanel.removeAll(); + + LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(250, 50); + ImageIcon icon = new ImageIcon(lineCaptcha.getImageBytes()); + + JLabel label = new JLabel(icon); + label.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1)); + captchaPanel.add(label); + + CaptchaData captchaData = lineCaptchaService.draw(); + decodeImage(captchaData); + + captchaData = circleCaptchaService.draw(); + decodeImage(captchaData); + + captchaData = shearCaptchaService.draw(); + decodeImage(captchaData); + + captchaData = gifCaptchaService.draw(); + decodeImage(captchaData); + + captchaData = blockPuzzleCaptchaService.draw(); + decodeImage(captchaData); + + captchaData = clickWorkCaptchaService.draw(); + decodeImage(captchaData); + + captchaPanel.revalidate(); + captchaPanel.repaint(); + } + + private void decodeImage(CaptchaData captchaData) { + ImageIcon icon = new ImageIcon(captchaData.captchaImage()); + + JLabel label = new JLabel(icon); + label.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1)); + captchaPanel.add(label); + + if (captchaData.backgroundImage() != null) { + icon = new ImageIcon(captchaData.backgroundImage()); + + label = new JLabel(icon); + label.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1)); + captchaPanel.add(label); + } + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + e.printStackTrace(); + } + new CaptchaJFrameDemo().setVisible(true); + } + }); + } +} diff --git a/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/anji/BlockPuzzleCaptchaServiceTest.java b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/anji/BlockPuzzleCaptchaServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d9e504f17b5e50585f85ffbc01e0f1f42e0b8fcd --- /dev/null +++ b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/anji/BlockPuzzleCaptchaServiceTest.java @@ -0,0 +1,81 @@ +package yunjiao.springboot.extension.captcha.anji; + +import com.anji.captcha.model.common.Const; +import com.anji.captcha.service.CaptchaCacheService; +import com.anji.captcha.service.CaptchaService; +import com.anji.captcha.service.impl.CaptchaServiceFactory; +import org.junit.jupiter.api.Test; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.captcha.Point; +import yunjiao.springboot.extension.common.util.GsonUtils; + +import java.awt.*; +import java.util.Properties; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * {@link BlockPuzzleCaptchaService} 单元测试用例 + * + * @author yangyunjiao + */ +public class BlockPuzzleCaptchaServiceTest { + private static final BlockPuzzleCaptchaService blockPuzzleCaptchaService; + + static { + Properties config = new Properties(); + config.put(Const.CAPTCHA_CACHETYPE, "local"); + config.put(Const.CAPTCHA_WATER_MARK, "我的水印"); + config.put(Const.CAPTCHA_FONT_TYPE, "WenQuanZhengHei.ttf"); + config.put(Const.CAPTCHA_TYPE, "default"); + config.put(Const.CAPTCHA_INTERFERENCE_OPTIONS, "0"); + config.put(Const.ORIGINAL_PATH_JIGSAW, ""); + config.put(Const.ORIGINAL_PATH_PIC_CLICK, ""); + config.put(Const.CAPTCHA_SLIP_OFFSET, "5"); + config.put(Const.CAPTCHA_AES_STATUS, "false"); + config.put(Const.CAPTCHA_WATER_FONT, "WenQuanZhengHei.ttf"); + // CacheUtil的定时任务存在泄露的问题 + config.put(Const.CAPTCHA_TIMING_CLEAR_SECOND, "0"); + + config.put(Const.CAPTCHA_FONT_SIZE, "25"); + config.put(Const.CAPTCHA_FONT_STYLE, Font.BOLD); + config.put(Const.CAPTCHA_WORD_COUNT, "4"); + + CaptchaService captchaService = CaptchaServiceFactory.getInstance(config); + CaptchaCacheService captchaCacheService = CaptchaServiceFactory.getCache("local"); + blockPuzzleCaptchaService = new BlockPuzzleCaptchaService(captchaService, + captchaCacheService, + 6); + } + + @Test + void whenDraw_thenOk() { + CaptchaData data = blockPuzzleCaptchaService.draw(); + assertThat(data.key()).isNotBlank(); + assertThat(data.backgroundImage()).isNotNull(); + assertThat(data.captchaImage()).isNotNull(); + assertThat(data.category()).isEqualTo(CaptchaCategory.blockPuzzle); + } + + @Test + void givenPoint_whenVerify_thenOK() { + CaptchaData data = blockPuzzleCaptchaService.draw(); + assertThat(blockPuzzleCaptchaService.verify(data.code(), data.code())).isTrue(); + + // 范围内 + Point original = GsonUtils.fromJson(data.code(), Point.class); + String userCode = GsonUtils.toJson(new Point(original.x() - 5, original.y() + 5)); + assertThat(blockPuzzleCaptchaService.verify(data.code(), userCode)).isTrue(); + + // x超出范围 + userCode = GsonUtils.toJson(new Point(original.x() - 7, original.y())); + assertThat(blockPuzzleCaptchaService.verify(data.code(), userCode)).isFalse(); + + // y超出范围 + userCode = GsonUtils.toJson(new Point(original.x(), original.y() + 7)); + assertThat(blockPuzzleCaptchaService.verify(data.code(), userCode)).isFalse(); + } + + +} diff --git a/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/anji/ClickWorkCaptchaServiceTest.java b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/anji/ClickWorkCaptchaServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7b713c57730f608c407c56cf3a72f7b326ba57d1 --- /dev/null +++ b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/anji/ClickWorkCaptchaServiceTest.java @@ -0,0 +1,98 @@ +package yunjiao.springboot.extension.captcha.anji; + +import com.anji.captcha.model.common.Const; +import com.anji.captcha.service.CaptchaCacheService; +import com.anji.captcha.service.CaptchaService; +import com.anji.captcha.service.impl.CaptchaServiceFactory; +import org.junit.jupiter.api.Test; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.captcha.Point; +import yunjiao.springboot.extension.common.util.GsonUtils; + +import java.awt.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * {@link ClickWorkCaptchaService} 单元测试用例 + * + * @author yangyunjiao + */ +public class ClickWorkCaptchaServiceTest { + private static final ClickWorkCaptchaService clickWorkCaptchaService; + + static { + Properties config = new Properties(); + config.put(Const.CAPTCHA_CACHETYPE, "local"); + config.put(Const.CAPTCHA_WATER_MARK, "我的水印"); + config.put(Const.CAPTCHA_FONT_TYPE, "WenQuanZhengHei.ttf"); + config.put(Const.CAPTCHA_TYPE, "default"); + config.put(Const.CAPTCHA_INTERFERENCE_OPTIONS, "0"); + config.put(Const.ORIGINAL_PATH_JIGSAW, ""); + config.put(Const.ORIGINAL_PATH_PIC_CLICK, ""); + config.put(Const.CAPTCHA_SLIP_OFFSET, "5"); + config.put(Const.CAPTCHA_AES_STATUS, "false"); + config.put(Const.CAPTCHA_WATER_FONT, "WenQuanZhengHei.ttf"); + // CacheUtil的定时任务存在泄露的问题 + config.put(Const.CAPTCHA_TIMING_CLEAR_SECOND, "0"); + + config.put(Const.CAPTCHA_FONT_SIZE, "25"); + config.put(Const.CAPTCHA_FONT_STYLE, Font.BOLD); + config.put(Const.CAPTCHA_WORD_COUNT, "4"); + + CaptchaService captchaService = CaptchaServiceFactory.getInstance(config); + CaptchaCacheService captchaCacheService = CaptchaServiceFactory.getCache("local"); + clickWorkCaptchaService = new ClickWorkCaptchaService(captchaService, + captchaCacheService, + 6); + } + + @Test + void whenDraw_thenOk() { + CaptchaData data = clickWorkCaptchaService.draw(); + assertThat(data.key()).isNotBlank(); + assertThat(data.backgroundImage()).isNull(); + assertThat(data.captchaImage()).isNotNull(); + assertThat(data.category()).isEqualTo(CaptchaCategory.clickWord); + } + + @Test + void givenPoint_whenVerify_thenOK() { + CaptchaData data = clickWorkCaptchaService.draw(); + assertThat(clickWorkCaptchaService.verify(data.code(), data.code())).isTrue(); + + // 范围内 + List originalList = GsonUtils.toList(data.code(), Point.class); + List userList = new ArrayList<>(); + for (int i = 0; i < originalList.size(); i++) { + Point original = originalList.get(i); + Point newPoint = new Point(original.x() - i, original.y() + i); + userList.add(newPoint); + } + assertThat(clickWorkCaptchaService.verify(data.code(), GsonUtils.toJson(userList))).isTrue(); + + // x超出范围 + userList.clear(); + for (int i = 0; i < originalList.size(); i++) { + Point original = originalList.get(i); + Point newPoint = new Point(original.x() - i*4, original.y()); + userList.add(newPoint); + } + assertThat(clickWorkCaptchaService.verify(data.code(), GsonUtils.toJson(userList))).isFalse(); + + // y超出范围 + userList.clear(); + for (int i = 0; i < originalList.size(); i++) { + Point original = originalList.get(i); + Point newPoint = new Point(original.x(), original.y() + i*4); + userList.add(newPoint); + } + assertThat(clickWorkCaptchaService.verify(data.code(), GsonUtils.toJson(userList))).isFalse(); + } + + +} diff --git a/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/CircleCaptchaServiceTest.java b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/CircleCaptchaServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9b7384ab71831c4bae17e97f5dacb5bccbc1f73f --- /dev/null +++ b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/CircleCaptchaServiceTest.java @@ -0,0 +1,62 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import org.junit.jupiter.api.Test; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.model.ColorType; + +import java.awt.*; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * {@link CircleCaptchaService} 单元测试用例 + * + * @author yangyunjiao + */ +public class CircleCaptchaServiceTest { + private static final CircleCaptchaService circleCaptchaService; + private static final CircleCaptchaBuilder builder; + + static { + Font font = new Font(null, Font.PLAIN, 36); + builder = new CircleCaptchaBuilder(); + builder.setWidth(250); + builder.setHeight(50); + builder.setInterfereCount(30); + builder.setBackgroundColor(ColorType.white); + builder.setFuzziness(2); + builder.setValidIgnoreCase(true); + builder.setFont(font); + builder.setGenerator(CodeGeneratorType.numAndChar.apply(6)); + circleCaptchaService = new CircleCaptchaService(builder); + } + + @Test + void whenDraw_thenOk() { + CaptchaData data = circleCaptchaService.draw(); + assertThat(data.key()).isNotBlank(); + assertThat(data.backgroundImage()).isNull(); + assertThat(data.captchaImage()).isNotNull(); + assertThat(data.category()).isEqualTo(CaptchaCategory.circle); + assertThat(data.code()).hasSize(6); + } + + @Test + void givenIgnoreCaseTrue_whenVerify_thenOK() { + builder.setValidIgnoreCase(true); + CaptchaData data = circleCaptchaService.draw(); + + String uperCode = data.code().toUpperCase(); + assertThat(circleCaptchaService.verify(data.code(), uperCode)).isTrue(); + } + + @Test + void givenIgnoreCaseFalse_whenVerify_thenOK() { + builder.setValidIgnoreCase(false); + CaptchaData data = circleCaptchaService.draw(); + + String uperCode = data.code().toUpperCase(); + assertThat(circleCaptchaService.verify(data.code(), uperCode)).isFalse(); + } +} diff --git a/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/GifCaptchaServiceTest.java b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/GifCaptchaServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..80cf999395e251cdc08559635cadce4a98029e9c --- /dev/null +++ b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/GifCaptchaServiceTest.java @@ -0,0 +1,67 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import org.junit.jupiter.api.Test; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.model.ColorType; + +import java.awt.*; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * {@link LineCaptchaService} 单元测试用例 + * + * @author yangyunjiao + */ +public class GifCaptchaServiceTest { + private static final GifCaptchaService gifCaptchaService; + private static final GifCaptchaBuilder builder; + + static { + Font font = new Font(null, Font.PLAIN, 36); + builder = new GifCaptchaBuilder(); + builder.setWidth(250); + builder.setHeight(50); + builder.setInterfereCount(10); + builder.setBackgroundColor(ColorType.white); + builder.setFuzziness(2); + builder.setValidIgnoreCase(true); + builder.setFont(font); + builder.setGenerator(CodeGeneratorType.lowerChar.apply(6)); + builder.setQuality(10); + builder.setRepeat(0); + builder.setMinColor(0); + builder.setMaxColor(255); + + gifCaptchaService = new GifCaptchaService(builder); + } + + @Test + void whenDraw_thenOk() { + CaptchaData data = gifCaptchaService.draw(); + assertThat(data.key()).isNotBlank(); + assertThat(data.backgroundImage()).isNull(); + assertThat(data.captchaImage()).isNotNull(); + assertThat(data.category()).isEqualTo(CaptchaCategory.gif); + assertThat(data.code()).hasSize(6); + } + + @Test + void givenIgnoreCaseTrue_whenVerify_thenOK() { + builder.setValidIgnoreCase(true); + CaptchaData data = gifCaptchaService.draw(); + + String uperCode = data.code().toUpperCase(); + assertThat(gifCaptchaService.verify(data.code(), uperCode)).isTrue(); + } + + @Test + void givenIgnoreCaseFalse_whenVerify_thenOK() { + builder.setValidIgnoreCase(false); + CaptchaData data = gifCaptchaService.draw(); + + String uperCode = data.code().toUpperCase(); + assertThat(gifCaptchaService.verify(data.code(), uperCode)).isFalse(); + } +} diff --git a/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/LineCaptchaServiceTest.java b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/LineCaptchaServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7ef00426fb3797b3bd353ead2673d238473bc21b --- /dev/null +++ b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/LineCaptchaServiceTest.java @@ -0,0 +1,62 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import org.junit.jupiter.api.Test; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.model.ColorType; + +import java.awt.*; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * {@link LineCaptchaService} 单元测试用例 + * + * @author yangyunjiao + */ +public class LineCaptchaServiceTest { + private static final LineCaptchaService lineCaptchaService; + private static final LineCaptchaBuilder builder; + + static { + Font font = new Font(null, Font.PLAIN, 36); + builder = new LineCaptchaBuilder(); + builder.setWidth(250); + builder.setHeight(50); + builder.setInterfereCount(60); + builder.setBackgroundColor(ColorType.white); + builder.setFuzziness(2); + builder.setValidIgnoreCase(true); + builder.setFont(font); + builder.setGenerator(CodeGeneratorType.lowerChar.apply(6)); + lineCaptchaService = new LineCaptchaService(builder); + } + + @Test + void whenDraw_thenOk() { + CaptchaData data = lineCaptchaService.draw(); + assertThat(data.key()).isNotBlank(); + assertThat(data.backgroundImage()).isNull(); + assertThat(data.captchaImage()).isNotNull(); + assertThat(data.category()).isEqualTo(CaptchaCategory.line); + assertThat(data.code()).hasSize(6); + } + + @Test + void givenIgnoreCaseTrue_whenVerify_thenOK() { + builder.setValidIgnoreCase(true); + CaptchaData data = lineCaptchaService.draw(); + + String uperCode = data.code().toUpperCase(); + assertThat(lineCaptchaService.verify(data.code(), uperCode)).isTrue(); + } + + @Test + void givenIgnoreCaseFalse_whenVerify_thenOK() { + builder.setValidIgnoreCase(false); + CaptchaData data = lineCaptchaService.draw(); + + String uperCode = data.code().toUpperCase(); + assertThat(lineCaptchaService.verify(data.code(), uperCode)).isFalse(); + } +} diff --git a/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/ShearCaptchaServiceTest.java b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/ShearCaptchaServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ba35f6cfe40880a37a83443c63abf12c454bbcf0 --- /dev/null +++ b/extensions/extension-captcha/src/test/java/yunjiao/springboot/extension/captcha/hutool/ShearCaptchaServiceTest.java @@ -0,0 +1,62 @@ +package yunjiao.springboot.extension.captcha.hutool; + +import org.junit.jupiter.api.Test; +import yunjiao.springboot.extension.common.captcha.CaptchaCategory; +import yunjiao.springboot.extension.common.captcha.CaptchaData; +import yunjiao.springboot.extension.common.model.ColorType; + +import java.awt.*; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * {@link ShearCaptchaService} 单元测试用例 + * + * @author yangyunjiao + */ +public class ShearCaptchaServiceTest { + private static final ShearCaptchaService shearCaptchaService; + private static final ShearCaptchaBuilder builder; + + static { + Font font = new Font(null, Font.PLAIN, 36); + builder = new ShearCaptchaBuilder(); + builder.setWidth(250); + builder.setHeight(50); + builder.setInterfereCount(4); + builder.setBackgroundColor(ColorType.white); + builder.setFuzziness(2); + builder.setValidIgnoreCase(true); + builder.setFont(font); + builder.setGenerator(CodeGeneratorType.numAndChar.apply(6)); + shearCaptchaService = new ShearCaptchaService(builder); + } + + @Test + void whenDraw_thenOk() { + CaptchaData data = shearCaptchaService.draw(); + assertThat(data.key()).isNotBlank(); + assertThat(data.backgroundImage()).isNull(); + assertThat(data.captchaImage()).isNotNull(); + assertThat(data.category()).isEqualTo(CaptchaCategory.shear); + assertThat(data.code()).hasSize(6); + } + + @Test + void givenIgnoreCaseTrue_whenVerify_thenOK() { + builder.setValidIgnoreCase(true); + CaptchaData data = shearCaptchaService.draw(); + + String uperCode = data.code().toUpperCase(); + assertThat(shearCaptchaService.verify(data.code(), uperCode)).isTrue(); + } + + @Test + void givenIgnoreCaseFalse_whenVerify_thenOK() { + builder.setValidIgnoreCase(false); + CaptchaData data = shearCaptchaService.draw(); + + String uperCode = data.code().toUpperCase(); + assertThat(shearCaptchaService.verify(data.code(), uperCode)).isFalse(); + } +} diff --git a/extensions/extension-common/README.md b/extensions/extension-common/README.md deleted file mode 100644 index 7d314579ae58484ad8edcff8498b7a89559c387d..0000000000000000000000000000000000000000 --- a/extensions/extension-common/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# spring-common - -通用工具集。 - -## maven - -```xml - - io.gitee.yunjiao-source - spring-common - ${revision} - -``` -## 使用指南 - -### TimestampIdGenerator - -当前时间戳的ID生成器,`Long类型`,提供静态方法生成ID。线程安全的,仅用于测试或示例 - -```text - final int SIZE = 3000; - Set idSet = IntStream.range(0, SIZE).parallel().mapToLong(i -> TimestampIdGenerator.next()).boxed() - .collect(Collectors.toSet()); - System.out.println(idSet.stream().skip(SIZE -10).collect(Collectors.toList())); -``` - -输出: -```text -[1755402971097584, 1755402971097585, 1755402971097598, 1755402971097599, 1755402971097596, 1755402971097597, 1755402971097594, 1755402971097595, 1755402971097592, 1755402971097593] -``` diff --git a/extensions/extension-common/pom.xml b/extensions/extension-common/pom.xml index f96697eeb252d925287e7e306930518b4bb1b49a..80b96925b1bcd52dc46034dc0cac5a0e09eeb3fe 100644 --- a/extensions/extension-common/pom.xml +++ b/extensions/extension-common/pom.xml @@ -3,7 +3,7 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extensions ${revision} @@ -14,5 +14,22 @@ Extension :: Common 通用工具 - + + + com.google.guava + guava + + + org.springframework + spring-core + + + cn.hutool + hutool-core + + + com.google.code.gson + gson + + \ No newline at end of file diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/algorithm/GaussianBlur.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/algorithm/GaussianBlur.java new file mode 100644 index 0000000000000000000000000000000000000000..b944ad5bfc5b7749efe489de834d691e7358ec68 --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/algorithm/GaussianBlur.java @@ -0,0 +1,158 @@ +package yunjiao.springboot.extension.common.algorithm; + +import java.awt.image.BufferedImage; + +/** + * 高斯模糊算法实现 + * + * @author yangyunjiao + */ +public final class GaussianBlur { + /** + * 轻度处理 + * + * @param image 原始图像 + * @return 模糊后的图像 + */ + public static BufferedImage gaussianBlurLight(BufferedImage image) { + return execute(image, 5); + } + + /** + * 中度处理 + * + * @param image 原始图像 + * @return 模糊后的图像 + */ + public static BufferedImage gaussianBlurMedium(BufferedImage image) { + return execute(image, 8); + } + + /** + * 重度处理 + * + * @param image 原始图像 + * @return 模糊后的图像 + */ + public static BufferedImage gaussianBlurHeavy(BufferedImage image) { + return execute(image, 11); + } + + /** + * 高斯模糊算法实现 + * + * @param image 原始图像 + * @param radius 模糊半径 + * @return 模糊后的图像 + */ + public static BufferedImage execute(BufferedImage image, int radius) { + int width = image.getWidth(); + int height = image.getHeight(); + + // 创建结果图像 + BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + + // 计算高斯核 + double[] kernel = createGaussianKernel(radius); + int kernelSize = kernel.length; + int kernelRadius = kernelSize / 2; + + // 临时存储中间结果 + int[] pixels = new int[width * height]; + int[] blurredPixels = new int[width * height]; + + // 获取像素数据 + image.getRGB(0, 0, width, height, pixels, 0, width); + + // 水平模糊 + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + double r = 0; + double g = 0; + double b = 0; + double a = 0; + + for (int i = -kernelRadius; i <= kernelRadius; i++) { + int pixelX = Math.min(Math.max(x + i, 0), width - 1); + int pixelIndex = y * width + pixelX; + int pixel = pixels[pixelIndex]; + + double weight = kernel[i + kernelRadius]; + + a += weight * ((pixel >> 24) & 0xFF); + r += weight * ((pixel >> 16) & 0xFF); + g += weight * ((pixel >> 8) & 0xFF); + b += weight * (pixel & 0xFF); + } + + int argb = ((int) a & 0xFF) << 24 + | ((int) r & 0xFF) << 16 + | ((int) g & 0xFF) << 8 + | ((int) b & 0xFF); + + blurredPixels[y * width + x] = argb; + } + } + + // 垂直模糊 + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + double r = 0; + double g = 0; + double b = 0; + double a = 0; + + for (int i = -kernelRadius; i <= kernelRadius; i++) { + int pixelY = Math.min(Math.max(y + i, 0), height - 1); + int pixelIndex = pixelY * width + x; + int pixel = blurredPixels[pixelIndex]; + + double weight = kernel[i + kernelRadius]; + + a += weight * ((pixel >> 24) & 0xFF); + r += weight * ((pixel >> 16) & 0xFF); + g += weight * ((pixel >> 8) & 0xFF); + b += weight * (pixel & 0xFF); + } + + int argb = ((int) a & 0xFF) << 24 + | ((int) r & 0xFF) << 16 + | ((int) g & 0xFF) << 8 + | ((int) b & 0xFF); + + result.setRGB(x, y, argb); + } + } + + return result; + } + + /** + * 创建高斯核 + * + * @param radius 模糊半径 + * @return 高斯核数组 + */ + public static double[] createGaussianKernel(int radius) { + int size = radius * 2 + 1; + double[] kernel = new double[size]; + double sigma = radius / 3.0; + double sigma22 = 2 * sigma * sigma; + double sqrtPiSigma22 = Math.sqrt(Math.PI * sigma22); + double total = 0; + + // 计算高斯函数值 + for (int i = -radius; i <= radius; i++) { + double distance = i * i; + kernel[i + radius] = Math.exp(-distance / sigma22) / sqrtPiSigma22; + total += kernel[i + radius]; + } + + // 归一化 + for (int i = 0; i < size; i++) { + kernel[i] /= total; + } + + return kernel; + } +} diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaCategory.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaCategory.java new file mode 100644 index 0000000000000000000000000000000000000000..fd31015c30e51c37cf5621354e3a6a2da6f2ade4 --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaCategory.java @@ -0,0 +1,41 @@ +package yunjiao.springboot.extension.common.captcha; + +import yunjiao.springboot.extension.common.lang.EnumCache; +import lombok.Getter; +import lombok.ToString; + +/** + * 验证码类别 + * + * @author yangyunjiao + */ +@Getter +@ToString +public enum CaptchaCategory { + line("png", "线段干扰验证码"), + circle("png", "圆圈干扰验证码"), + shear("png", "扭曲干扰验证码"), + gif("gif", "GIF验证码"), + blockPuzzle("png", "滑块拼图验证码"), + clickWord("png", "文字点选验证码"), + rotatePuzzle("png", "旋转拼图验证码"); + + /** + * 描述 + */ + private final String description; + + /** + * 扩展名 + */ + private final String ext; + + CaptchaCategory(String ext, String description) { + this.ext = ext; + this.description = description; + } + + static { + EnumCache.registerByName(CaptchaCategory.class, CaptchaCategory.values()); + } +} diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaData.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaData.java new file mode 100644 index 0000000000000000000000000000000000000000..3dcf82b449e70a8a16b6fe6868c66259d60b2d97 --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaData.java @@ -0,0 +1,73 @@ +package yunjiao.springboot.extension.common.captcha; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Base64; + +/** + * 验证码数据 + * + * @author yangyunjiao + */ +@Getter +@Setter +@ToString +@Accessors(fluent = true, chain = true) +public class CaptchaData implements Serializable { + /** + * 验证码唯一标识,通常是uuid字符 + */ + private String key; + + /** + * 验证码图片 + */ + private byte[] captchaImage; + + /** + * 背景图片 + */ + private byte[] backgroundImage; + + /** + * 验证码 + */ + private String code; + + /** + * 分类 + */ + private CaptchaCategory category; + + /** + * 转换成图片字符串 + * + * @return 可能空 + */ + public String captchaImageBase64Url() { + if (captchaImage == null) { + return null; + } + + String base64 = Base64.getEncoder().encodeToString(captchaImage); + return "data:image/" + category.getExt() + ";base64," + base64; + } + + /** + * 转换成背景图片字符串 + * + * @return 可能空 + */ + public String backgroundImageBase64Url() { + if (backgroundImage == null) { + return null; + } + + String base64 = Base64.getEncoder().encodeToString(backgroundImage); + return "data:image/" + category.getExt() + ";base64," + base64; + } +} diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaReponse.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaReponse.java new file mode 100644 index 0000000000000000000000000000000000000000..31700de3e13830ef002a22e906bccf4ed3ef3696 --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaReponse.java @@ -0,0 +1,41 @@ +package yunjiao.springboot.extension.common.captcha; + +import lombok.Data; + +/** + * 验证码响应 + * + * @author yangyunjiao + */ +@Data +public class CaptchaReponse { + /** + * 验证码唯一标识,通常是uuid字符 + */ + private String key; + + /** + * 验证码图片 + */ + private String captchaImageBase64; + + /** + * 背景图片 + */ + private String backgroundImageBase64; + + + /** + * 分类 + */ + private CaptchaCategory category; + + public static CaptchaReponse of(CaptchaData data) { + CaptchaReponse reponse = new CaptchaReponse(); + reponse.setCategory(data.category()); + reponse.setKey(data.key()); + reponse.setBackgroundImageBase64(data.backgroundImageBase64Url()); + reponse.setCaptchaImageBase64(data.captchaImageBase64Url()); + return reponse; + } +} diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaService.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaService.java new file mode 100644 index 0000000000000000000000000000000000000000..056bad7725738adf4831bb236c0f932be70da9ec --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaService.java @@ -0,0 +1,31 @@ +package yunjiao.springboot.extension.common.captcha; + +/** + * 验证码服务接口 + * + * @author yangyunjiao + */ +public interface CaptchaService { + /** + * 验证码绘制 + * + * @return 验证码信息 + */ + CaptchaData draw(); + + /** + * 校验验证码 + * + * @param originalCode 原始验证码 + * @param userCode 用户输入验证码 + * @return 相同返回true,否则false + */ + boolean verify(String originalCode, String userCode); + + /** + * 获取分类 + * + * @return 验证码类别 + */ + CaptchaCategory getCategory(); +} diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaValidate.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaValidate.java new file mode 100644 index 0000000000000000000000000000000000000000..5749d635abdac7b7fd0d06de5bf4544debdc58df --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/CaptchaValidate.java @@ -0,0 +1,27 @@ +package yunjiao.springboot.extension.common.captcha; + +import lombok.Data; + +/** + * 验证码校验对象 + * + * @author yangyunjiao + */ +@Data +public class CaptchaValidate { + /** + * 验证码唯一标识,通常是uuid字符 + */ + private String key; + + /** + * 验证码 + */ + private String code; + + + /** + * 分类 + */ + private CaptchaCategory category; +} diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/Point.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/Point.java new file mode 100644 index 0000000000000000000000000000000000000000..ece897906752fa12be7375bd2bdb1e56671f0d58 --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/captcha/Point.java @@ -0,0 +1,9 @@ +package yunjiao.springboot.extension.common.captcha; + +/** + * 坐标 + * + * @author yangyunjiao + */ +public record Point(Integer x, Integer y) { +} diff --git a/extensions/extension-common/src/main/java/io/yunjiao/extension/common/generator/TimestampIdGenerator.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/generator/TimestampIdGenerator.java similarity index 88% rename from extensions/extension-common/src/main/java/io/yunjiao/extension/common/generator/TimestampIdGenerator.java rename to extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/generator/TimestampIdGenerator.java index 2131aba586b7332e58bb78890c7365236f885057..5b9b9ed1024047a24fa60da2bfc27b4b44089e91 100644 --- a/extensions/extension-common/src/main/java/io/yunjiao/extension/common/generator/TimestampIdGenerator.java +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/generator/TimestampIdGenerator.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.common.generator; +package yunjiao.springboot.extension.common.generator; import java.util.concurrent.atomic.AtomicLong; diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/lang/EnumCache.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/lang/EnumCache.java new file mode 100644 index 0000000000000000000000000000000000000000..9417e63167ea08deaac3ad5f10922b8ae1058905 --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/lang/EnumCache.java @@ -0,0 +1,204 @@ +package yunjiao.springboot.extension.common.lang; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 枚举缓存 + *

+ *

+ * 参考文章:如何高效优雅的使用java枚举 + * + * @author yangyunjiao + */ +public class EnumCache { + + /** + * 以枚举任意值构建的缓存结构 + **/ + static final Map>, Map>> CACHE_BY_VALUE = new ConcurrentHashMap<>(); + + /** + * 以枚举名称构建的缓存结构 + **/ + static final Map>, Map>> CACHE_BY_NAME = new ConcurrentHashMap<>(); + + /** + * 枚举静态块加载标识缓存结构 + */ + static final Map>, Boolean> LOADED = new ConcurrentHashMap<>(); + + /** + * 锁对象 + */ + private static final Object lock = new Object(); + + /** + * 以枚举名称构建缓存,在枚举的静态块里面调用 + * + * @param clazz 必须值 + * @param values 必须值 + * @param 枚举类型 + */ + public static > void registerByName(Class clazz, E[] values) { + Map> map = new ConcurrentHashMap<>(); + for (E v : values) { + map.put(v.name(), v); + } + CACHE_BY_NAME.put(clazz, map); + } + + /** + * 以枚举转换出的任意值构建缓存,在枚举的静态块里面调用 + * + * @param clazz 必须值 + * @param values 必须值 + * @param enumMapping 必须值 + * @param 枚举类型 + */ + public static > void registerByValue(Class clazz, E[] values, EnumMapping enumMapping) { + if (CACHE_BY_VALUE.containsKey(clazz)) { + throw new RuntimeException(String.format("枚举%s已经构建过value缓存,不允许重复构建", clazz.getSimpleName())); + } + Map> map = new ConcurrentHashMap<>(); + for (E v : values) { + Object value = enumMapping.value(v); + if (map.containsKey(value)) { + throw new RuntimeException(String.format("枚举%s存在相同的值%s映射同一个枚举%s.%s", clazz.getSimpleName(), value, clazz.getSimpleName(), v)); + } + map.put(value, v); + } + CACHE_BY_VALUE.put(clazz, map); + } + + /** + * 从以枚举名称构建的缓存中通过枚举名获取枚举 + * + * @param clazz 必须值 + * @param name 可以空 + * @return 实例 + * @param 枚举类型 + */ + public static > E findByName(Class clazz, String name) { + return find(clazz, name, CACHE_BY_NAME, null); + } + + /** + * 从以枚举名称构建的缓存中通过枚举名获取枚举 + * + * @param clazz 必须值 + * @param name 可以空 + * @param defaultEnum 可以空 + * @param 枚举类型 + * @return 实例 + */ + public static > E findByName(Class clazz, String name, E defaultEnum) { + return find(clazz, name, CACHE_BY_NAME, defaultEnum); + } + + /** + * 从以枚举转换值构建的缓存中通过枚举转换值获取枚举 + * + * @param clazz 必须值 + * @param value 可以空 + * @param 枚举类型 + * @return 实例 + */ + public static > E findByValue(Class clazz, Object value) { + return find(clazz, value, CACHE_BY_VALUE, null); + } + + /** + * 从以枚举转换值构建的缓存中通过枚举转换值获取枚举 + * + * @param clazz 必须值 + * @param value 可以空 + * @param defaultEnum 可以空 + * @param 枚举类型 + * @return 实例 + */ + public static > E findByValue(Class clazz, Object value, E defaultEnum) { + return find(clazz, value, CACHE_BY_VALUE, defaultEnum); + } + + /** + * + * @param clazz 必须值 + * @param obj 可以空 + * @param cache 必须值 + * @param defaultEnum 可以空 + * @return 实例 + * @param 枚举类型 + */ + private static > E find(Class clazz, Object obj, Map>, Map>> cache, E defaultEnum) { + Map> map = cache.get(clazz); + if (map == null) { + executeEnumStatic(clazz);// 触发枚举静态块执行 + map = cache.get(clazz);// 执行枚举静态块后重新获取缓存 + } + if (map == null) { + String msg = null; + if (cache == CACHE_BY_NAME) { + msg = String.format( + "枚举%s还没有注册到枚举缓存中,请在%s.static代码块中加入如下代码 : EnumCache.registerByName(%s.class, %s.values());", + clazz.getSimpleName(), + clazz.getSimpleName(), + clazz.getSimpleName(), + clazz.getSimpleName() + ); + } + if (cache == CACHE_BY_VALUE) { + msg = String.format( + "枚举%s还没有注册到枚举缓存中,请在%s.static代码块中加入如下代码 : EnumCache.registerByValue(%s.class, %s.values(), %s::getXxx);", + clazz.getSimpleName(), + clazz.getSimpleName(), + clazz.getSimpleName(), + clazz.getSimpleName(), + clazz.getSimpleName() + ); + } + throw new RuntimeException(msg); + } + if (obj == null) { + return defaultEnum; + } + Enum result = map.get(obj); + return result == null ? defaultEnum : (E) result; + } + + /** + * + * @param clazz 必须值 + * @param 枚举类型 + */ + private static > void executeEnumStatic(Class clazz) { + if (!LOADED.containsKey(clazz)) { + synchronized (lock) { + if (!LOADED.containsKey(clazz)) { + try { + // 目的是让枚举类的static块运行,static块没有执行完是会阻塞在此的 + Class.forName(clazz.getName()); + LOADED.put(clazz, true); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + } + } + + /** + * 枚举缓存映射器函数式接口 + */ + @FunctionalInterface + public interface EnumMapping> { + /** + * 自定义映射器 + * + * @param e 枚举 + * @return 映射关系,最终体现到缓存中 + */ + Object value(E e); + } + +} diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/model/ColorType.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/model/ColorType.java new file mode 100644 index 0000000000000000000000000000000000000000..5d868d504e086f47e162f89fa5252802e07f8bd8 --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/model/ColorType.java @@ -0,0 +1,85 @@ +package yunjiao.springboot.extension.common.model; + +import lombok.Getter; + +import java.awt.*; + +/** + * 颜色类型 + * + * @author yangyunjiao + */ +@Getter +public enum ColorType { + /** + * 白色 + */ + white(Color.WHITE), + + /** + * 浅灰色 + */ + lightGray(Color.LIGHT_GRAY), + + /** + * 灰色 + */ + gray(Color.GRAY), + + /** + * 深灰色 + */ + darkGray(Color.DARK_GRAY), + + + /** + * 黑色 + */ + black(Color.BLACK), + + /** + * 红色 + */ + red(Color.RED), + + /** + * 粉红色 + */ + pink(Color.PINK), + + /** + * 橘色 + */ + orange(Color.ORANGE), + + /** + * 黄色 + */ + yellow(Color.YELLOW), + + /** + * 绿色 + */ + green(Color.GREEN), + + /** + * 洋红色 + */ + magenta(Color.MAGENTA), + + /** + * 青色 + */ + cyan(Color.CYAN), + + /** + * 蓝色 + */ + blue(Color.BLUE); + + private final Color mapping; + + ColorType(Color mapping) { + this.mapping = mapping; + } +} diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/model/FontStyle.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/model/FontStyle.java new file mode 100644 index 0000000000000000000000000000000000000000..45cf7ba00810189ba71887158ea9fa6034cb15d5 --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/model/FontStyle.java @@ -0,0 +1,34 @@ +package yunjiao.springboot.extension.common.model; + +import lombok.Getter; + +import java.awt.*; + +/** + * 字体风格 + * + * @author yangyunjiao + */ +@Getter +public enum FontStyle { + /** + * 正常体 + */ + plain(Font.PLAIN), + + /** + * 粗体 + */ + bold(Font.BOLD), + + /** + * 斜体 + */ + italic(Font.ITALIC); + + private final int mapping; + + FontStyle(int mapping) { + this.mapping = mapping; + } +} diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/model/TransparencyType.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/model/TransparencyType.java new file mode 100644 index 0000000000000000000000000000000000000000..ea369292973cbdc7dd39bc17f46ab87ee379ce32 --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/model/TransparencyType.java @@ -0,0 +1,79 @@ +package yunjiao.springboot.extension.common.model; + +import lombok.Getter; + +import java.awt.*; + +/** + * 透明度类型 + * + * @author yangyunjiao + */ +@Getter +public enum TransparencyType { + /** + * {@link AlphaComposite#Clear} + */ + clear(AlphaComposite.Clear), + + /** + * {@link AlphaComposite#Src} + */ + src(AlphaComposite.Src), + + /** + * {@link AlphaComposite#Dst} + */ + dst(AlphaComposite.Dst), + + /** + * {@link AlphaComposite#SrcOver} + */ + srcOver(AlphaComposite.SrcOver), + + /** + * {@link AlphaComposite#DstOver} + */ + dstOver(AlphaComposite.DstOver), + + /** + * {@link AlphaComposite#SrcIn} + */ + srcIn(AlphaComposite.SrcIn), + + /** + * {@link AlphaComposite#DstIn} + */ + dstIn(AlphaComposite.DstIn), + + /** + * {@link AlphaComposite#SrcOut} + */ + srcOut(AlphaComposite.SrcOut), + + /** + * {@link AlphaComposite#DstOut} + */ + dstOut(AlphaComposite.DstOut), + + /** + * {@link AlphaComposite#SrcAtop} + */ + srcAtop(AlphaComposite.SrcAtop), + + /** + * {@link AlphaComposite#DstAtop} + */ + dstAtop(AlphaComposite.DstAtop), + + /** + * {@link AlphaComposite#Xor} + */ + xOr(AlphaComposite.Xor); + + private final AlphaComposite mapping; + + TransparencyType(AlphaComposite mapping) { + this.mapping = mapping; + } +} diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/util/CommonRuntimeException.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/util/CommonRuntimeException.java new file mode 100644 index 0000000000000000000000000000000000000000..5ff666190c793ce1c8126a7e6bd6941b23d5fab5 --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/util/CommonRuntimeException.java @@ -0,0 +1,27 @@ +package yunjiao.springboot.extension.common.util; + +/** + * 通用异常 + * + * @author yangyunjiao + */ +public class CommonRuntimeException extends RuntimeException { + public CommonRuntimeException() { + } + + public CommonRuntimeException(String message) { + super(message); + } + + public CommonRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public CommonRuntimeException(Throwable cause) { + super(cause); + } + + public CommonRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/util/GsonUtils.java b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/util/GsonUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..05da869e4f8e64609dd6bdbc659bffa32506a6fd --- /dev/null +++ b/extensions/extension-common/src/main/java/yunjiao/springboot/extension/common/util/GsonUtils.java @@ -0,0 +1,122 @@ +package yunjiao.springboot.extension.common.util; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; + +import java.io.Reader; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; + +/** + * {@link Gson} 工具箱 + * + * @author yangyunjiao + */ +public final class GsonUtils { + + private static final Gson GSON = new GsonBuilder() + .setDateFormat("yyyy-MM-dd HH:mm:ss") // 设置日期格式 + .disableHtmlEscaping() // 禁止转义HTML标签 + .setPrettyPrinting() // 格式化输出 + .create(); + + private GsonUtils() { + // 工具类,防止实例化 + } + + /** + * 将对象转换为JSON字符串 + * @param obj 要转换的对象 + * @return JSON字符串 + */ + public static String toJson(Object obj) { + return GSON.toJson(obj); + } + + /** + * 将JSON字符串转换为指定类型的对象 + * @param json JSON字符串 + * @param clazz 目标类型 + * @param 泛型类型 + * @return 转换后的对象 + */ + public static T fromJson(String json, Class clazz) { + return GSON.fromJson(json, clazz); + } + + /** + * 将JSON字符串转换为指定Type的对象 + * @param json JSON字符串 + * @param type 目标Type + * @param 泛型类型 + * @return 转换后的对象 + */ + public static T fromJson(String json, Type type) { + return GSON.fromJson(json, type); + } + + /** + * 从Reader读取JSON并转换为指定类型的对象 + * @param reader Reader对象 + * @param clazz 目标类型 + * @param 泛型类型 + * @return 转换后的对象 + */ + public static T fromJson(Reader reader, Class clazz) { + return GSON.fromJson(reader, clazz); + } + + /** + * 将JSON字符串转换为List + * @param json JSON字符串 + * @param clazz List中元素的类型 + * @param 泛型类型 + * @return 转换后的List + */ + public static List toList(String json, Class clazz) { + Type type = TypeToken.getParameterized(List.class, clazz).getType(); + return GSON.fromJson(json, type); + } + + /** + * 将JSON字符串转换为Map + * @param json JSON字符串 + * @param keyClass Map中key的类型 + * @param valueClass Map中value的类型 + * @param key的泛型类型 + * @param value的泛型类型 + * @return 转换后的Map + */ + public static Map toMap(String json, Class keyClass, Class valueClass) { + Type type = TypeToken.getParameterized(Map.class, keyClass, valueClass).getType(); + return GSON.fromJson(json, type); + } + + /** + * 格式化JSON字符串 + * @param json 未格式化的JSON字符串 + * @return 格式化后的JSON字符串 + */ + public static String formatJson(String json) { + JsonElement jsonElement = JsonParser.parseString(json); + return GSON.toJson(jsonElement); + } + + /** + * 判断字符串是否为有效的JSON + * @param json 要检查的字符串 + * @return 是否为有效的JSON + */ + public static boolean isValidJson(String json) { + try { + JsonElement jsonElement = JsonParser.parseString(json); + return jsonElement != null; + } catch (Exception e) { + return false; + } + } +} diff --git a/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/algorithm/GaussianBlurJFrameDemo.java b/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/algorithm/GaussianBlurJFrameDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..febb0bd67e514289e2a5c83a1046af6ce8cad1e7 --- /dev/null +++ b/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/algorithm/GaussianBlurJFrameDemo.java @@ -0,0 +1,199 @@ +package yunjiao.springboot.extension.common.algorithm; + +import lombok.Getter; + +import javax.imageio.ImageIO; +import javax.swing.*; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +/** + * {@link GaussianBlur} 可视化界面 + * + * @author yangyunjiao + */ +public class GaussianBlurJFrameDemo extends JFrame { + private BufferedImage originalImage; + private BufferedImage blurredImage; + private final JLabel imageLabel; + private final JSlider radiusSlider; + private final JComboBox intensityComboBox; + + // 模糊强度枚举 + @Getter + public enum BlurIntensity { + LIGHT(1, 3), + MEDIUM(4, 7), + HEAVY(8, 15); + + private final int minRadius; + private final int maxRadius; + + BlurIntensity(int minRadius, int maxRadius) { + this.minRadius = minRadius; + this.maxRadius = maxRadius; + } + + public int getRadius() { + return (minRadius + maxRadius) / 2; // 返回中间值作为默认半径 + } + + } + + public GaussianBlurJFrameDemo() { + setTitle("Java高斯模糊算法 - 支持强度设置"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(1000, 700); + setLocationRelativeTo(null); + + // 创建界面组件 + imageLabel = new JLabel(); + imageLabel.setHorizontalAlignment(SwingConstants.CENTER); + JScrollPane scrollPane = new JScrollPane(imageLabel); + + // 模糊强度选择 + intensityComboBox = new JComboBox<>(new String[]{"轻度模糊", "中度模糊", "重度模糊", "自定义"}); + intensityComboBox.setSelectedIndex(1); // 默认选择中度模糊 + intensityComboBox.addActionListener(e -> updateRadiusBasedOnIntensity()); + + // 半径滑块 + radiusSlider = new JSlider(1, 30, BlurIntensity.MEDIUM.getRadius()); + radiusSlider.setMajorTickSpacing(5); + radiusSlider.setMinorTickSpacing(1); + radiusSlider.setPaintTicks(true); + radiusSlider.setPaintLabels(true); + radiusSlider.setBorder(BorderFactory.createTitledBorder("模糊半径")); + + // 更新滑块范围基于强度选择 + //updateRadiusRange(); + + JButton openButton = new JButton("打开图片"); + JButton saveButton = new JButton("保存图片"); + + // 按钮面板 + JPanel buttonPanel = new JPanel(); + buttonPanel.add(openButton); + buttonPanel.add(saveButton); + + // 强度选择面板 + JPanel intensityPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + intensityPanel.add(new JLabel("模糊强度:")); + intensityPanel.add(intensityComboBox); + + // 控制面板 + JPanel controlPanel = new JPanel(new BorderLayout()); + controlPanel.add(intensityPanel, BorderLayout.NORTH); + controlPanel.add(radiusSlider, BorderLayout.CENTER); + controlPanel.add(buttonPanel, BorderLayout.SOUTH); + + // 主布局 + setLayout(new BorderLayout()); + add(scrollPane, BorderLayout.CENTER); + add(controlPanel, BorderLayout.SOUTH); + + // 添加事件监听器 + openButton.addActionListener(e -> openImage()); + saveButton.addActionListener(e -> saveImage()); + radiusSlider.addChangeListener(e -> { + System.out.println(e); + applyBlur(); + }); + } + + private void updateRadiusBasedOnIntensity() { + int selectedIndex = intensityComboBox.getSelectedIndex(); + //updateRadiusRange(); + + if (selectedIndex < 3) { // 不是"自定义" + BlurIntensity intensity = BlurIntensity.values()[selectedIndex]; + radiusSlider.setValue(intensity.getRadius()); + } + } + + private void updateRadiusRange() { + int selectedIndex = intensityComboBox.getSelectedIndex(); + if (selectedIndex < 3) { + BlurIntensity intensity = BlurIntensity.values()[selectedIndex]; + radiusSlider.setMinimum(intensity.getMinRadius()); + radiusSlider.setMaximum(intensity.getMaxRadius()); + } else { + // 自定义模式下使用完整范围 + radiusSlider.setMinimum(1); + radiusSlider.setMaximum(30); + } + } + + private void openImage() { + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setDialogTitle("选择图片"); + fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + + int result = fileChooser.showOpenDialog(this); + if (result == JFileChooser.APPROVE_OPTION) { + try { + File file = fileChooser.getSelectedFile(); + originalImage = ImageIO.read(file); + displayImage(originalImage); + applyBlur(); + } catch (IOException ex) { + JOptionPane.showMessageDialog(this, "无法加载图片: " + ex.getMessage(), + "错误", JOptionPane.ERROR_MESSAGE); + } + } + } + + private void saveImage() { + if (blurredImage == null) { + JOptionPane.showMessageDialog(this, "没有图片可保存", + "警告", JOptionPane.WARNING_MESSAGE); + return; + } + + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setDialogTitle("保存图片"); + fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + + int result = fileChooser.showSaveDialog(this); + if (result == JFileChooser.APPROVE_OPTION) { + try { + File file = fileChooser.getSelectedFile(); + ImageIO.write(blurredImage, "png", file); + JOptionPane.showMessageDialog(this, "图片保存成功!", + "成功", JOptionPane.INFORMATION_MESSAGE); + } catch (IOException ex) { + JOptionPane.showMessageDialog(this, "无法保存图片: " + ex.getMessage(), + "错误", JOptionPane.ERROR_MESSAGE); + } + } + } + + private void applyBlur() { + if (originalImage == null) return; + + int radius = radiusSlider.getValue(); + long startTime = System.currentTimeMillis(); + blurredImage = GaussianBlur.execute(originalImage, radius); + long stopTome = System.currentTimeMillis(); + System.out.println("耗时:" + (stopTome - startTime)/1000); + displayImage(blurredImage); + } + + private void displayImage(BufferedImage image) { + Image scaledImage = image.getScaledInstance( + Math.min(800, image.getWidth()), + Math.min(600, image.getHeight()), + Image.SCALE_SMOOTH + ); + ImageIcon icon = new ImageIcon(scaledImage); + imageLabel.setIcon(icon); + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> { + GaussianBlurJFrameDemo app = new GaussianBlurJFrameDemo(); + app.setVisible(true); + }); + } +} diff --git a/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/algorithm/GaussianBlurTest.java b/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/algorithm/GaussianBlurTest.java new file mode 100644 index 0000000000000000000000000000000000000000..02091e61e869a3205a5afbab2ab2454a8b262cfb --- /dev/null +++ b/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/algorithm/GaussianBlurTest.java @@ -0,0 +1,262 @@ +package yunjiao.springboot.extension.common.algorithm; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.awt.image.BufferedImage; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * {@link GaussianBlur} 单元测试用例 + * + * @author yangyunjiao + */ +public class GaussianBlurTest { + + @Test + @DisplayName("测试全黑图像模糊") + void testBlurAllBlackImage() { + // 创建全黑图像 + BufferedImage blackImage = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB); + for (int x = 0; x < 10; x++) { + for (int y = 0; y < 10; y++) { + blackImage.setRGB(x, y, 0xFF000000); // 黑色完全不透明 + } + } + + // 应用高斯模糊 + BufferedImage result = GaussianBlur.execute(blackImage, 5); + + // 验证结果仍然是全黑 + for (int x = 0; x < 10; x++) { + for (int y = 0; y < 10; y++) { + assertEquals(0xFF000000, result.getRGB(x, y), + "全黑图像模糊后应该仍然是全黑"); + } + } + } + + @Test + @DisplayName("测试全白图像模糊") + void testBlurAllWhiteImage() { + // 创建全白图像 + BufferedImage whiteImage = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB); + for (int x = 0; x < 10; x++) { + for (int y = 0; y < 10; y++) { + whiteImage.setRGB(x, y, 0xFFFFFFFF); // 白色完全不透明 + } + } + + // 应用高斯模糊 + BufferedImage result = GaussianBlur.execute(whiteImage, 5); + + // 验证结果仍然是全白(允许轻微的颜色变化) + for (int x = 0; x < 10; x++) { + for (int y = 0; y < 10; y++) { + int rgb = result.getRGB(x, y); + // 检查所有通道都接近255 + int alpha = (rgb >> 24) & 0xFF; + int red = (rgb >> 16) & 0xFF; + int green = (rgb >> 8) & 0xFF; + int blue = rgb & 0xFF; + + assertTrue(alpha >= 250 && red >= 250 && green >= 250 && blue >= 250, + "全白图像模糊后应该仍然是接近全白"); + } + } + } + + @Test + @DisplayName("测试单像素图像模糊") + void testBlurSinglePixelImage() { + // 创建单像素图像 + BufferedImage singlePixel = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); + singlePixel.setRGB(0, 0, 0xFFFF0000); // 红色 + + // 应用高斯模糊 + BufferedImage result = GaussianBlur.execute(singlePixel, 3); + + // 验证结果仍然是相同的颜色 + assertEquals(0xFFFF0000, result.getRGB(0, 0), + "单像素图像模糊后应该保持不变"); + } + + @Test + @Disabled("测试失败") + @DisplayName("测试模糊半径为零") + void testBlurWithZeroRadius() { + // 创建测试图像 + BufferedImage testImage = new BufferedImage(5, 5, BufferedImage.TYPE_INT_ARGB); + for (int x = 0; x < 5; x++) { + for (int y = 0; y < 5; y++) { + testImage.setRGB(x, y, (x + y) * 0x08040201); // 生成一些变化 + } + } + + // 应用半径为0的高斯模糊 + BufferedImage result = GaussianBlur.execute(testImage, 0); + + // 验证图像没有变化 + for (int x = 0; x < 5; x++) { + for (int y = 0; y < 5; y++) { + assertEquals(testImage.getRGB(x, y), result.getRGB(x, y), + "零半径模糊应该保持图像不变"); + } + } + } + + @Test + @DisplayName("测试模糊半径边界处理") + void testBlurEdgeHandling() { + // 创建测试图像,四角有不同的颜色 + BufferedImage testImage = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB); + + // 设置四角颜色 + testImage.setRGB(0, 0, 0xFFFF0000); // 左上角红色 + testImage.setRGB(9, 0, 0xFF00FF00); // 右上角绿色 + testImage.setRGB(0, 9, 0xFF0000FF); // 左下角蓝色 + testImage.setRGB(9, 9, 0xFFFFFF00); // 右下角黄色 + + // 应用高斯模糊 + BufferedImage result = GaussianBlur.execute(testImage, 5); + + // 验证四角颜色已经混合(不再是纯色) + int topLeft = result.getRGB(0, 0); + int topRight = result.getRGB(9, 0); + int bottomLeft = result.getRGB(0, 9); + int bottomRight = result.getRGB(9, 9); + + // 检查颜色通道值(应该不是极值) + assertNotEquals(0xFFFF0000, topLeft, "左上角颜色应该被模糊"); + assertNotEquals(0xFF00FF00, topRight, "右上角颜色应该被模糊"); + assertNotEquals(0xFF0000FF, bottomLeft, "左下角颜色应该被模糊"); + assertNotEquals(0xFFFFFF00, bottomRight, "右下角颜色应该被模糊"); + } + + @Test + @DisplayName("测试不同模糊半径的效果") + void testDifferentBlurRadius() { + // 创建测试图像 - 黑白棋盘 + BufferedImage chessboard = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB); + for (int x = 0; x < 10; x++) { + for (int y = 0; y < 10; y++) { + chessboard.setRGB(x, y, (x + y) % 2 == 0 ? 0xFFFFFFFF : 0xFF000000); + } + } + + // 应用小半径模糊 + BufferedImage smallBlur = GaussianBlur.execute(chessboard, 1); + + // 应用大半径模糊 + BufferedImage largeBlur = GaussianBlur.execute(chessboard, 10); + + // 计算两幅图像的差异 + double difference = calculateImageDifference(smallBlur, largeBlur); + + // 大半径模糊应该产生更模糊的结果 + assertTrue(difference > 0.1, "不同半径的模糊应该产生不同的结果"); + } + + @Test + @DisplayName("测试模糊后的图像尺寸不变") + void testBlurPreservesDimensions() { + // 创建测试图像 + BufferedImage testImage = new BufferedImage(15, 20, BufferedImage.TYPE_INT_ARGB); + + // 应用高斯模糊 + BufferedImage result = GaussianBlur.execute(testImage, 5); + + // 验证尺寸不变 + assertEquals(testImage.getWidth(), result.getWidth(), "模糊后图像宽度应该不变"); + assertEquals(testImage.getHeight(), result.getHeight(), "模糊后图像高度应该不变"); + } + + @Test + @DisplayName("测试高斯核生成") + void testGaussianKernelGeneration() { + // 测试半径为1的高斯核 + double[] kernel1 = GaussianBlur.createGaussianKernel(1); + assertEquals(3, kernel1.length, "半径1的高斯核应该有3个元素"); + + // 检查核的和约为1(由于浮点精度,可能不是精确的1) + double sum = 0; + for (double value : kernel1) { + sum += value; + } + assertEquals(1.0, sum, 1e-10, "高斯核的总和应该为1"); + + // 检查核是对称的 + assertEquals(kernel1[0], kernel1[2], 1e-10, "高斯核应该是对称的"); + + // 测试半径为2的高斯核 + double[] kernel2 = GaussianBlur.createGaussianKernel(2); + assertEquals(5, kernel2.length, "半径2的高斯核应该有5个元素"); + + // 检查核的和约为1 + sum = 0; + for (double value : kernel2) { + sum += value; + } + assertEquals(1.0, sum, 1e-10, "高斯核的总和应该为1"); + + // 检查核是对称的 + assertEquals(kernel2[0], kernel2[4], 1e-10, "高斯核应该是对称的"); + assertEquals(kernel2[1], kernel2[3], 1e-10, "高斯核应该是对称的"); + } + + @Test + @DisplayName("测试极端模糊半径") + void testExtremeBlurRadius() { + // 创建测试图像 + BufferedImage testImage = new BufferedImage(5, 5, BufferedImage.TYPE_INT_ARGB); + testImage.setRGB(2, 2, 0xFFFF0000); // 中心为红色 + + // 应用非常大的模糊半径 + BufferedImage result = GaussianBlur.execute(testImage, 100); + + // 验证图像没有崩溃,并且所有像素都有值 + for (int x = 0; x < 5; x++) { + for (int y = 0; y < 5; y++) { + assertNotNull(result.getRGB(x, y), "极端半径模糊不应该产生空像素"); + } + } + } + + // 辅助方法:计算两幅图像的差异(基于像素值的均方根误差) + private double calculateImageDifference(BufferedImage img1, BufferedImage img2) { + int width = img1.getWidth(); + int height = img1.getHeight(); + long sum = 0; + int count = 0; + + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + int rgb1 = img1.getRGB(x, y); + int rgb2 = img2.getRGB(x, y); + + // 计算每个通道的差异 + int a1 = (rgb1 >> 24) & 0xFF; + int r1 = (rgb1 >> 16) & 0xFF; + int g1 = (rgb1 >> 8) & 0xFF; + int b1 = rgb1 & 0xFF; + + int a2 = (rgb2 >> 24) & 0xFF; + int r2 = (rgb2 >> 16) & 0xFF; + int g2 = (rgb2 >> 8) & 0xFF; + int b2 = rgb2 & 0xFF; + + // 累加平方差异 + sum += (a1 - a2) * (a1 - a2); + sum += (r1 - r2) * (r1 - r2); + sum += (g1 - g2) * (g1 - g2); + sum += (b1 - b2) * (b1 - b2); + count += 4; + } + } + + // 计算均方根误差 + return Math.sqrt((double) sum / count); + } +} diff --git a/extensions/extension-common/src/test/java/io/yunjiao/extension/common/generator/TimestampIdGeneratorTest.java b/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/generator/TimestampIdGeneratorTest.java similarity index 85% rename from extensions/extension-common/src/test/java/io/yunjiao/extension/common/generator/TimestampIdGeneratorTest.java rename to extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/generator/TimestampIdGeneratorTest.java index 88a69de6c2f849ee00e6e64ebb68e6843d4f573d..809f354cea875708b5a5769ac8f29d06fe4001bd 100644 --- a/extensions/extension-common/src/test/java/io/yunjiao/extension/common/generator/TimestampIdGeneratorTest.java +++ b/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/generator/TimestampIdGeneratorTest.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.common.generator; +package yunjiao.springboot.extension.common.generator; import org.junit.jupiter.api.Test; @@ -15,7 +15,7 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class TimestampIdGeneratorTest { @Test - public void test() { + public void givenSzie_whenParllelGenerator_thenOk() { final int SIZE = 3000; Set idSet = IntStream.range(0, SIZE).parallel().mapToLong(i -> TimestampIdGenerator.next()).boxed() .collect(Collectors.toSet()); diff --git a/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/lang/EnumCacheTest.java b/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/lang/EnumCacheTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3d188ada55ae4d6d2795ee6125f08a3be1df35d6 --- /dev/null +++ b/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/lang/EnumCacheTest.java @@ -0,0 +1,68 @@ +package yunjiao.springboot.extension.common.lang; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * {@link EnumCache} 单元测试用例 + * + * @author yangyunjiao + */ +public class EnumCacheTest { + + @Test + void givenName_whenFindByName_thenReturnOk() { + StatusEnum status = EnumCache.findByName(StatusEnum.class, "SUCCESS"); + assertThat(status).isEqualTo(StatusEnum.SUCCESS); + } + + @Test + void givenWrongName_whenFindByName_thenReturnNull() { + StatusEnum status = EnumCache.findByName(StatusEnum.class, "SUCCESS1"); + assertThat(status).isNull(); + } + + @Test + void givenValue_whenFindByValue_thenReturnOk() { + StatusEnum status = EnumCache.findByValue(StatusEnum.class, "S"); + assertThat(status).isEqualTo(StatusEnum.SUCCESS); + } + + @Test + void givenWrongValue_whenFindByName_thenReturnNull() { + StatusEnum status = EnumCache.findByName(StatusEnum.class, "s"); + assertThat(status).isNull(); + } + + + enum StatusEnum { + INIT("I", "初始化"), + PROCESSING("P", "处理中"), + SUCCESS("S", "成功"), + FAIL("F", "失败"); + + private String code; + private String desc; + + StatusEnum(String code, String desc) { + this.code = code; + this.desc = desc; + } + + public String getCode() { + return code; + } + + public String getDesc() { + return desc; + } + + static { + // 通过名称构建缓存,通过EnumCache.findByName(StatusEnum.class,"SUCCESS",null);调用能获取枚举 + EnumCache.registerByName(StatusEnum.class, StatusEnum.values()); + // 通过code构建缓存,通过EnumCache.findByValue(StatusEnum.class,"S",null);调用能获取枚举 + EnumCache.registerByValue(StatusEnum.class, StatusEnum.values(), StatusEnum::getCode); + } + } +} diff --git a/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/util/GsonUtilsTest.java b/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/util/GsonUtilsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..32ee0986223064f3fd3eb0c5b8479a594a1f0fac --- /dev/null +++ b/extensions/extension-common/src/test/java/yunjiao/springboot/extension/common/util/GsonUtilsTest.java @@ -0,0 +1,154 @@ +package yunjiao.springboot.extension.common.util; + +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import org.junit.jupiter.api.Test; + +import java.io.StringReader; +import java.lang.reflect.Type; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +/** + * {@link GsonUtils} 单元测试用例 + * + * @author yangyunjiao + */ +public class GsonUtilsTest { + // 测试用的简单对象 + @Data + static class TestUser { + // getters and setters + private String name; + private int age; + private Date birthDate; + + public TestUser() {} + + public TestUser(String name, int age, Date birthDate) { + this.name = name; + this.age = age; + this.birthDate = birthDate; + } + } + + @Test + public void testToJson() { + TestUser user = new TestUser("张三", 25, new Date(91, 0, 1)); + String json = GsonUtils.toJson(user); + + assertThat(json).contains("\"name\": \"张三\""); + assertThat(json).contains("\"age\": 25"); + assertThat(json).contains("\"birthDate\": "); + } + + @Test + public void testFromJson() { + String json = "{\"name\":\"李四\",\"age\":30,\"birthDate\":\"1991-01-01 00:00:00\"}"; + TestUser user = GsonUtils.fromJson(json, TestUser.class); + + assertEquals("李四", user.getName()); + assertEquals(30, user.getAge()); + assertNotNull(user.getBirthDate()); + } + + @Test + public void testFromJsonWithReader() { + String json = "{\"name\":\"王五\",\"age\":35,\"birthDate\":\"1991-01-01 00:00:00\"}"; + StringReader reader = new StringReader(json); + TestUser user = GsonUtils.fromJson(reader, TestUser.class); + + assertEquals("王五", user.getName()); + assertEquals(35, user.getAge()); + assertNotNull(user.getBirthDate()); + } + + @Test + public void testToList() { + String json = "[{\"name\":\"张三\",\"age\":25,\"birthDate\":\"1991-01-01 00:00:00\"}," + + "{\"name\":\"李四\",\"age\":30,\"birthDate\":\"1991-01-01 00:00:00\"}]"; + + List users = GsonUtils.toList(json, TestUser.class); + + assertEquals(2, users.size()); + assertEquals("张三", users.get(0).getName()); + assertEquals("李四", users.get(1).getName()); + } + + @Test + public void testToMap() { + String json = "{\"user1\":{\"name\":\"张三\",\"age\":25,\"birthDate\":\"1991-01-01 00:00:00\"}," + + "\"user2\":{\"name\":\"李四\",\"age\":30,\"birthDate\":\"1991-01-01 00:00:00\"}}"; + + Map userMap = GsonUtils.toMap(json, String.class, TestUser.class); + + assertEquals(2, userMap.size()); + assertTrue(userMap.containsKey("user1")); + assertTrue(userMap.containsKey("user2")); + assertEquals("张三", userMap.get("user1").getName()); + assertEquals("李四", userMap.get("user2").getName()); + } + + @Test + public void testFormatJson() { + String unformattedJson = "{\"name\":\"张三\",\"age\":25,\"birthDate\":\"1991-01-01 00:00:00\"}"; + String formattedJson = GsonUtils.formatJson(unformattedJson); + + assertTrue(formattedJson.contains("\n")); + assertTrue(formattedJson.contains(" ")); // 检查是否有缩进 + } + + @Test + public void testIsValidJson() { + // 测试有效JSON + assertTrue(GsonUtils.isValidJson("{\"name\":\"张三\"}")); + assertTrue(GsonUtils.isValidJson("[1, 2, 3]")); + + // 测试无效JSON + assertFalse(GsonUtils.isValidJson("{\"name\":\"张三\"")); + assertFalse(GsonUtils.isValidJson("invalid json")); + } + + @Test + public void testFromJsonWithType() { + String json = "[{\"name\":\"张三\",\"age\":25,\"birthDate\":\"1991-01-01 00:00:00\"}," + + "{\"name\":\"李四\",\"age\":30,\"birthDate\":\"1991-01-01 00:00:00\"}]"; + + Type listType = TypeToken.getParameterized(List.class, TestUser.class).getType(); + List users = GsonUtils.fromJson(json, listType); + + assertEquals(2, users.size()); + assertEquals("张三", users.get(0).getName()); + assertEquals("李四", users.get(1).getName()); + } + + @Test + public void testNullHandling() { + // 测试null对象转JSON + String json = GsonUtils.toJson(null); + assertEquals("null", json); + + // 测试null字符串转对象 + TestUser user = GsonUtils.fromJson((String) null, TestUser.class); + assertNull(user); + + // 测试空字符串转对象 + user = GsonUtils.fromJson("", TestUser.class); + assertNull(user); + } + + @Test + public void testInvalidJsonConversion() { + String invalidJson = "{\"name\":\"张三\",\"age\":}"; // 无效的JSON + + assertThatThrownBy(() -> GsonUtils.fromJson(invalidJson, TestUser.class)) + .isInstanceOf(JsonSyntaxException.class) + .hasMessageContaining("Expected value at line"); + } +} diff --git a/extensions/extension-common/src/test/resources/images/input.png b/extensions/extension-common/src/test/resources/images/input.png new file mode 100644 index 0000000000000000000000000000000000000000..a0e7910d2083a8bb42a1407618f577993acf8500 Binary files /dev/null and b/extensions/extension-common/src/test/resources/images/input.png differ diff --git a/extensions/extension-id/pom.xml b/extensions/extension-id/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..900dfdac9e8cd04226b233a51305b37d9040ac41 --- /dev/null +++ b/extensions/extension-id/pom.xml @@ -0,0 +1,27 @@ + + + + io.gitee.yunjiao-source.spring-boot + extensions + ${revision} + + 4.0.0 + + extension-id + jar + Extension :: Id + 身份标识号扩展 + + + + io.gitee.yunjiao-source.spring-boot + extension-common + + + cn.hutool + hutool-core + + + \ No newline at end of file diff --git a/extensions/extension-id/src/main/java/yunjiao/springboot/extension/id/_Id.java b/extensions/extension-id/src/main/java/yunjiao/springboot/extension/id/_Id.java new file mode 100644 index 0000000000000000000000000000000000000000..8af7028c1dc8fedfbdaf9d80cc24c90d0140bdbc --- /dev/null +++ b/extensions/extension-id/src/main/java/yunjiao/springboot/extension/id/_Id.java @@ -0,0 +1,9 @@ +package yunjiao.springboot.extension.id; + +/** + * _Id + * + * @author yangyunjiao + */ +public class _Id { +} diff --git a/extensions/extension-querydsl/pom.xml b/extensions/extension-querydsl/pom.xml index 35d0657c9ac1540dc9df9af9d6b2d5af38e6c6b3..9f3a8f8e79234ee9508f6fea1a2a7f0d4c74e9da 100644 --- a/extensions/extension-querydsl/pom.xml +++ b/extensions/extension-querydsl/pom.xml @@ -3,7 +3,7 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extensions ${revision} diff --git a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/QSpecification.java b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/QSpecification.java similarity index 99% rename from extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/QSpecification.java rename to extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/QSpecification.java index 6077727d5293bea540195c9f22713258b378cbdf..ad14e50c1de7b6e43ccb44ade658b42e4a5f9cda 100644 --- a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/QSpecification.java +++ b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/QSpecification.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl; +package yunjiao.springboot.extension.querydsl; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Predicate; diff --git a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/QueryDSLUtils.java b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/QueryDSLUtils.java similarity index 97% rename from extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/QueryDSLUtils.java rename to extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/QueryDSLUtils.java index bb4740eddea5866d5b155bef5cdf0f31443d9484..58e1714d61f0d3f7c689f26bba7393fd0f5eee04 100644 --- a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/QueryDSLUtils.java +++ b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/QueryDSLUtils.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl; +package yunjiao.springboot.extension.querydsl; import com.querydsl.core.types.Expression; import com.querydsl.core.types.Order; diff --git a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/SpecificationComposition.java b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/SpecificationComposition.java similarity index 97% rename from extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/SpecificationComposition.java rename to extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/SpecificationComposition.java index 919e24ebe2123ab1ff069d84f30723b56256885f..7adb35ffba741f043162fa27bd8f7d5530669d53 100644 --- a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/SpecificationComposition.java +++ b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/SpecificationComposition.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl; +package yunjiao.springboot.extension.querydsl; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Predicate; diff --git a/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/_Querydsl.java b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/_Querydsl.java new file mode 100644 index 0000000000000000000000000000000000000000..7c605858dd0ef4774e9339e4033b1286f01e3b65 --- /dev/null +++ b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/_Querydsl.java @@ -0,0 +1,9 @@ +package yunjiao.springboot.extension.querydsl; + +/** + * _Querydsl + * + * @author yangyunjiao + */ +public class _Querydsl { +} diff --git a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/jpa/JPAQueryCurdExecutor.java b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/jpa/JPAQueryCurdExecutor.java similarity index 99% rename from extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/jpa/JPAQueryCurdExecutor.java rename to extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/jpa/JPAQueryCurdExecutor.java index 4ca430bdaca6e1ded78c3259473c8aa6c684a540..12135ef7960d1cae4e1be80c045a92ba567d561c 100644 --- a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/jpa/JPAQueryCurdExecutor.java +++ b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/jpa/JPAQueryCurdExecutor.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl.jpa; +package yunjiao.springboot.extension.querydsl.jpa; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.NonUniqueResultException; @@ -8,7 +8,7 @@ import com.querydsl.core.types.Predicate; import com.querydsl.jpa.impl.JPADeleteClause; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAUpdateClause; -import io.yunjiao.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.QSpecification; import jakarta.persistence.EntityNotFoundException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.data.domain.Page; diff --git a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/jpa/JPAQueryRepositorySupport.java b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/jpa/JPAQueryRepositorySupport.java similarity index 97% rename from extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/jpa/JPAQueryRepositorySupport.java rename to extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/jpa/JPAQueryRepositorySupport.java index 9eea118a627d5da26fd17f07d44d53b5af985806..ae7036e654537eb08a7d4129f7f27ad1ec0eddbb 100644 --- a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/jpa/JPAQueryRepositorySupport.java +++ b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/jpa/JPAQueryRepositorySupport.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl.jpa; +package yunjiao.springboot.extension.querydsl.jpa; import com.querydsl.core.Tuple; import com.querydsl.core.types.EntityPath; @@ -7,8 +7,8 @@ import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.EntityPathBase; import com.querydsl.core.types.dsl.PathBuilder; import com.querydsl.jpa.impl.*; -import io.yunjiao.extension.querydsl.QSpecification; -import io.yunjiao.extension.querydsl.QueryDSLUtils; +import yunjiao.springboot.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.QueryDSLUtils; import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; diff --git a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/sql/SQLQueryCurdExecutor.java b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/sql/SQLQueryCurdExecutor.java similarity index 99% rename from extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/sql/SQLQueryCurdExecutor.java rename to extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/sql/SQLQueryCurdExecutor.java index 894f9a8313c0a31c320aeb272fd561b40f8fb4bb..a0e40e00523420cf970e70a2ffd44b07c5124c3c 100644 --- a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/sql/SQLQueryCurdExecutor.java +++ b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/sql/SQLQueryCurdExecutor.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl.sql; +package yunjiao.springboot.extension.querydsl.sql; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.NonUniqueResultException; @@ -8,7 +8,7 @@ import com.querydsl.core.types.Predicate; import com.querydsl.sql.SQLQuery; import com.querydsl.sql.dml.SQLDeleteClause; import com.querydsl.sql.dml.SQLUpdateClause; -import io.yunjiao.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.QSpecification; import jakarta.persistence.EntityNotFoundException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.data.domain.Page; diff --git a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/sql/SQLQueryRepositorySupport.java b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/sql/SQLQueryRepositorySupport.java similarity index 97% rename from extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/sql/SQLQueryRepositorySupport.java rename to extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/sql/SQLQueryRepositorySupport.java index c3441b4e06a22965dba0e52851431b72c0cccf29..4981e9eea2c380791d52fd435f851d151bc9fa2f 100644 --- a/extensions/extension-querydsl/src/main/java/io/yunjiao/extension/querydsl/sql/SQLQueryRepositorySupport.java +++ b/extensions/extension-querydsl/src/main/java/yunjiao/springboot/extension/querydsl/sql/SQLQueryRepositorySupport.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl.sql; +package yunjiao.springboot.extension.querydsl.sql; import com.querydsl.core.Tuple; import com.querydsl.core.types.Expression; @@ -12,8 +12,8 @@ import com.querydsl.sql.dml.SQLDeleteClause; import com.querydsl.sql.dml.SQLInsertClause; import com.querydsl.sql.dml.SQLMergeClause; import com.querydsl.sql.dml.SQLUpdateClause; -import io.yunjiao.extension.querydsl.QSpecification; -import io.yunjiao.extension.querydsl.QueryDSLUtils; +import yunjiao.springboot.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.QueryDSLUtils; import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; diff --git a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/QSpecificationTest.java b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/QSpecificationTest.java similarity index 94% rename from extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/QSpecificationTest.java rename to extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/QSpecificationTest.java index 18b8b684e43b141011ff9df783a5ac1b324ff02c..15953aabe3a8e8b15a6094f323ab5f2ae6ea0165 100644 --- a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/QSpecificationTest.java +++ b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/QSpecificationTest.java @@ -1,8 +1,8 @@ -package io.yunjiao.extension.querydsl; +package yunjiao.springboot.extension.querydsl; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Predicate; -import io.yunjiao.extension.querydsl.sql.QUsers; +import yunjiao.springboot.extension.querydsl.sql.QUsers; import org.junit.jupiter.api.Test; import java.sql.Date; @@ -18,19 +18,19 @@ import static org.assertj.core.api.Assertions.assertThat; public class QSpecificationTest { @Test - void givenOne_thenAnd() { + void givenOne_whenAnd() { QSpecification spec = name(); assertThat(create(spec).toString()).isEqualTo("users.name = abc"); } @Test - void givenTrue_thenAnd() { + void givenTwo_whenAnd() { QSpecification spec = name().and(age()); assertThat(create(spec).toString()).isEqualTo("users.name = abc && users.age >= 18"); } @Test - void givenThree_thenAnd() { + void givenThree_whenAnd() { QSpecification spec = name().and(age()).and(email()); assertThat(create(spec).toString()).isEqualTo("users.name = abc && users.age >= 18 && users.email = abc@qq.com"); @@ -39,7 +39,7 @@ public class QSpecificationTest { } @Test - void givenNull_thenAnd() { + void givenNull_whenAnd() { QSpecification spec = name().and(nullable()).and(age()).and(email()); assertThat(create(spec).toString()).isEqualTo("users.name = abc && users.age >= 18 && users.email = abc@qq.com"); @@ -48,7 +48,7 @@ public class QSpecificationTest { } @Test - void and() { + void givenNull_whenAndMulti() { QSpecification spec = nullable().and(age(), email(), birthDateEq()); assertThat(create(spec).toString()).isEqualTo("users.age >= 18 && users.email = abc@qq.com && users.birthDate = 1970-01-01"); @@ -57,7 +57,7 @@ public class QSpecificationTest { } @Test - void andNot() { + void whenAndNot() { QSpecification spec = name().and(age()).andNot(email()); assertThat(create(spec).toString()).isEqualTo("users.name = abc && users.age >= 18 && !(users.email = abc@qq.com)"); @@ -75,19 +75,19 @@ public class QSpecificationTest { } @Test - void andAnyOf() { + void whenAndAnyOf() { QSpecification spec = name().andAnyOf(age(), email()); assertThat(create(spec).toString()).isEqualTo("users.name = abc && (users.age >= 18 || users.email = abc@qq.com)"); } @Test - void orAllOf() { + void whenOrAllOf() { QSpecification spec = name().orAllOf(age(), email()); assertThat(create(spec).toString()).isEqualTo("users.name = abc || users.age >= 18 && users.email = abc@qq.com"); } @Test - void not() { + void whenNot() { QSpecification spec = QSpecification.not(name()); assertThat(create(spec).toString()).isEqualTo("!(users.name = abc)"); @@ -108,7 +108,7 @@ public class QSpecificationTest { } @Test - void or() { + void whenOr() { QSpecification spec = name(); assertThat(create(spec).toString()).isEqualTo("users.name = abc"); @@ -123,7 +123,7 @@ public class QSpecificationTest { } @Test - void orNot() { + void whenOrNot() { QSpecification spec = name().orNot(age()).orNot(email()).and(birthDateEq()); assertThat(create(spec).toString()).isEqualTo("(users.name = abc || !(users.age >= 18) || !(users.email = abc@qq.com)) && users.birthDate = 1970-01-01"); @@ -135,7 +135,7 @@ public class QSpecificationTest { } @Test - void orAnd() { + void whenOrAnd() { QSpecification spec = name().or(age()).and(email()); assertThat(create(spec).toString()).isEqualTo("(users.name = abc || users.age >= 18) && users.email = abc@qq.com"); @@ -153,7 +153,7 @@ public class QSpecificationTest { } @Test - void where() { + void whenWhere() { QSpecification spec = QSpecification.where(name()); assertThat(create(spec).toString()).isEqualTo("users.name = abc"); diff --git a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/jpa/JPAQueryRepositorySupportTest.java b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/jpa/JPAQueryRepositorySupportTest.java similarity index 97% rename from extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/jpa/JPAQueryRepositorySupportTest.java rename to extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/jpa/JPAQueryRepositorySupportTest.java index f487ae4ff776f13d384690685658eeaed35ba84b..2990dd5bbf5f2ba07866e9a7bc398dc52ff5b60e 100644 --- a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/jpa/JPAQueryRepositorySupportTest.java +++ b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/jpa/JPAQueryRepositorySupportTest.java @@ -1,8 +1,8 @@ -package io.yunjiao.extension.querydsl.jpa; +package yunjiao.springboot.extension.querydsl.jpa; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import io.yunjiao.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.QSpecification; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityNotFoundException; @@ -64,7 +64,7 @@ public class JPAQueryRepositorySupportTest { } @Test - void giveSingleName_whenFindSingleByName_thenOk() { + void givenSingleName_whenFindSingleByName_thenOk() { assertThat(repository.findSingleByName("zhangs")) .isPresent() .hasValueSatisfying(user -> { @@ -73,7 +73,7 @@ public class JPAQueryRepositorySupportTest { } @Test - void giveWrongName_whenFindSingleByName_thenOk() { + void givenWrongName_whenFindSingleByName_thenOk() { assertThat(repository.findSingleByName("lis")).isEmpty(); } @@ -237,7 +237,7 @@ public class JPAQueryRepositorySupportTest { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan("io.yunjiao"); + em.setPackagesToScan("yunjiao.springboot"); em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); Properties properties = new Properties(); diff --git a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/jpa/Order.java b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/jpa/Order.java similarity index 91% rename from extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/jpa/Order.java rename to extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/jpa/Order.java index 70af3b290073e7f5f65240a32cc6ca3a2acd12e2..068813e9e924b1a3555133cd9a30251e55ef27ed 100644 --- a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/jpa/Order.java +++ b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/jpa/Order.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl.jpa; +package yunjiao.springboot.extension.querydsl.jpa; import jakarta.persistence.*; import lombok.Data; diff --git a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/jpa/User.java b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/jpa/User.java similarity index 94% rename from extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/jpa/User.java rename to extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/jpa/User.java index 01c0df813abafaf41ff5dbb8dc70f86a2e933f81..9c9b670553102774ad28a925076ee4008e1c6d87 100644 --- a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/jpa/User.java +++ b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/jpa/User.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl.jpa; +package yunjiao.springboot.extension.querydsl.jpa; import jakarta.persistence.*; import lombok.Data; diff --git a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/Order.java b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/Order.java similarity index 84% rename from extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/Order.java rename to extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/Order.java index ce5a2c7c6d0d453c53d8cf67ec0c393d398ff4ba..a835fb975bf5400cbede9f3c8b0b48376edc6600 100644 --- a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/Order.java +++ b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/Order.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl.sql; +package yunjiao.springboot.extension.querydsl.sql; import lombok.Data; diff --git a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/QOrders.java b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/QOrders.java similarity index 98% rename from extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/QOrders.java rename to extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/QOrders.java index d790e0f3082f8643aa410474b18c01fce0bd9d3d..9d0dc24452d499665d2c04a0961be9cfdfdd8a7a 100644 --- a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/QOrders.java +++ b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/QOrders.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl.sql; +package yunjiao.springboot.extension.querydsl.sql; import com.querydsl.core.types.Path; import com.querydsl.core.types.PathMetadata; diff --git a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/QUsers.java b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/QUsers.java similarity index 98% rename from extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/QUsers.java rename to extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/QUsers.java index 6a75061b9713a4f47542f49daff146ec91c1af1a..bd9b490724531f18a5836ba2c9fb3e0806839439 100644 --- a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/QUsers.java +++ b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/QUsers.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl.sql; +package yunjiao.springboot.extension.querydsl.sql; import com.querydsl.core.types.Path; import com.querydsl.core.types.PathMetadata; diff --git a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/SQLQueryRepositorySupportTest.java b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/SQLQueryRepositorySupportTest.java similarity index 92% rename from extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/SQLQueryRepositorySupportTest.java rename to extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/SQLQueryRepositorySupportTest.java index d001b3ee2c23c728fcd018098818e3026063d3d7..432b7dce4abf3bcfa3f4b8c729cf31eeef6d8ac8 100644 --- a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/SQLQueryRepositorySupportTest.java +++ b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/SQLQueryRepositorySupportTest.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl.sql; +package yunjiao.springboot.extension.querydsl.sql; import com.querydsl.core.types.Projections; import com.querydsl.sql.H2Templates; @@ -6,8 +6,9 @@ import com.querydsl.sql.SQLQuery; import com.querydsl.sql.SQLQueryFactory; import com.querydsl.sql.spring.SpringConnectionProvider; import com.querydsl.sql.spring.SpringExceptionTranslator; -import io.yunjiao.extension.querydsl.QSpecification; +import yunjiao.springboot.extension.querydsl.QSpecification; import jakarta.persistence.EntityNotFoundException; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -63,8 +64,8 @@ public class SQLQueryRepositorySupportTest { } @Test - void giveSingleName_whenFindSingleByName_thenOk() { - assertThat(repository.findSingleByName("zhangs")) + void givenSingleName_whenFindSingleByName_thenOk() { + Assertions.assertThat(repository.findSingleByName("zhangs")) .isPresent() .hasValueSatisfying(user -> { assertThat(user.getName()).isEqualTo("zhangs"); @@ -72,8 +73,8 @@ public class SQLQueryRepositorySupportTest { } @Test - void giveWrongName_whenFindSingleByName_thenOk() { - assertThat(repository.findSingleByName("lis")).isEmpty(); + void givenWrongName_whenFindSingleByName_thenOk() { + Assertions.assertThat(repository.findSingleByName("lis")).isEmpty(); } @Test @@ -88,7 +89,7 @@ public class SQLQueryRepositorySupportTest { @Test void whenFindList() { - assertThat(repository.findList("Michael Miller", 23, new Date(0))).hasSize(2); + Assertions.assertThat(repository.findList("Michael Miller", 23, new Date(0))).hasSize(2); } @Test @@ -97,7 +98,7 @@ public class SQLQueryRepositorySupportTest { assertThat(users.getTotalPages()).isEqualTo(3); assertThat(users.getNumberOfElements()).isEqualTo(5); assertThat(users.getTotalElements()).isEqualTo(15); - assertThat(users.getContent()) + Assertions.assertThat(users.getContent()) .hasSize(5) .first() .extracting(User::getName) @@ -110,7 +111,7 @@ public class SQLQueryRepositorySupportTest { assertThat(users.getTotalPages()).isEqualTo(3); assertThat(users.getNumberOfElements()).isEqualTo(5); assertThat(users.getTotalElements()).isEqualTo(15); - assertThat(users.getContent()) + Assertions.assertThat(users.getContent()) .hasSize(5) .first() .extracting(User::getName) @@ -121,7 +122,7 @@ public class SQLQueryRepositorySupportTest { @Test void whenFindUserByOrderStatus() { List users = repository.findUserByOrderStatus(); - assertThat(users).hasSize(1).first().extracting(User::getName).isEqualTo("Michael Miller"); + Assertions.assertThat(users).hasSize(1).first().extracting(User::getName).isEqualTo("Michael Miller"); } @Test @@ -129,7 +130,7 @@ public class SQLQueryRepositorySupportTest { Pair> uo = repository.findUserAndOrders(5L); assertThat(uo).isNotNull(); assertThat(uo.getFirst()).extracting(User::getName).isEqualTo("Michael Miller"); - assertThat(uo.getSecond()).hasSize(2); + Assertions.assertThat(uo.getSecond()).hasSize(2); } @Repository diff --git a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/User.java b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/User.java similarity index 84% rename from extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/User.java rename to extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/User.java index c67c520a219b3c59ca7526f4be01d1d2195c6104..abb9fa0d0101864e9506f428cd808350dd03ebf4 100644 --- a/extensions/extension-querydsl/src/test/java/io/yunjiao/extension/querydsl/sql/User.java +++ b/extensions/extension-querydsl/src/test/java/yunjiao/springboot/extension/querydsl/sql/User.java @@ -1,4 +1,4 @@ -package io.yunjiao.extension.querydsl.sql; +package yunjiao.springboot.extension.querydsl.sql; import lombok.Data; diff --git a/extensions/extension-querydsl/src/test/resources/logback-test.xml b/extensions/extension-querydsl/src/test/resources/logback-test.xml index 8f4c6ad064a66932d7e6af822a363e29595ffbc8..5563ef33756c37685e7239460b37647595682f25 100644 --- a/extensions/extension-querydsl/src/test/resources/logback-test.xml +++ b/extensions/extension-querydsl/src/test/resources/logback-test.xml @@ -1,6 +1,6 @@ - + diff --git a/extensions/pom.xml b/extensions/pom.xml index 917a232afe76fed5dab160d3a89f4d4d455675a0..2aef7492eaf92cc1a40fa68cfceebff8a5de2348 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -3,7 +3,7 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot dependencies ${revision} ../dependencies/pom.xml @@ -19,12 +19,15 @@ extension-common extension-apijson extension-querydsl + extension-captcha + extension-id com.google.guava guava + provided org.slf4j diff --git a/pom.xml b/pom.xml index 5cbbcf22df5cce85b19594fba2fca162ab3604dc..804cc8ca8c335157254c10ed4624ce66af91f5ba 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot spring-boot ${revision} pom @@ -14,8 +14,8 @@ https://gitee.com/yunjiao-source/yunjiao-spring-boot - 3.5.x.2 - 3.5.4 + 0.3.0 + 3.0.13 3.6.0 1.6 @@ -27,11 +27,7 @@ extensions dependencies autoconfigure - spring-boot-starter-querydsl-sql - spring-boot-starter-querydsl-jpa - spring-boot-starter-hutool - spring-boot-starter-apijson-fastjson2 - spring-boot-starter-apijson-gson + starters @@ -102,6 +98,7 @@ central true + ${revision} diff --git a/projects/rest-query-language/README.md b/projects/README.md similarity index 50% rename from projects/rest-query-language/README.md rename to projects/README.md index 1a12925c0ad193bcbf765c87a0cb78327f160f89..3203b1be379bdcdeb2819467cbca8ed359542129 100644 --- a/projects/rest-query-language/README.md +++ b/projects/README.md @@ -1,8 +1,15 @@ -# rest-query-language +# projects -[Building a REST Query Language](https://www.baeldung.com/spring-rest-api-query-search-language-tutorial) +很多有意思的应用,都来自网络。 -## 使用指南 +## rest-query-language + +“REST Query Language”通常指的是一种用于对RESTful API的资源进行查询、过滤、排序等操作的语言或语法规范。它的核心目的是让客户端能够更灵活、 +高效地获取他们需要的特定数据,而不是简单地获取服务器返回的完整资源表示。 + +参考文章[Building a REST Query Language](https://www.baeldung.com/spring-rest-api-query-search-language-tutorial) + +使用指南 http://localhost:8080/users/criteria?search=lastName:doe,age%3E25 http://localhost:8080/users/spec?search=lastName:doe,age%3E25 @@ -16,3 +23,6 @@ http://localhost:8080/users/api/querydsl?age=22&age=26 http://localhost:8080/users/spec/adv?search=( firstName:john OR firstName:tom ) AND age%3E22 + + + diff --git a/projects/pom.xml b/projects/pom.xml index 8028f8273b81a68e073e88220a5ed0f646ecc958..cd714e9649842884a510ec6a96bf6a138676db2e 100644 --- a/projects/pom.xml +++ b/projects/pom.xml @@ -3,9 +3,9 @@ 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"> - io.gitee.yunjiao-source - spring-boot-starter-parent - 3.5.x.2 + io.gitee.yunjiao-source.spring-boot + starter-parent + 0.3.0 4.0.0 @@ -21,7 +21,7 @@ - 3.5.x.2 + 0.3.0 1.5.0 2.1.0 diff --git a/projects/rest-query-language/pom.xml b/projects/rest-query-language/pom.xml index db062e85cf6678ec20fe9cc29d7a609ba29b016b..2e76c3af7dd5e49641ad4db5eadd8ea57062eb9f 100644 --- a/projects/rest-query-language/pom.xml +++ b/projects/rest-query-language/pom.xml @@ -3,7 +3,7 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot projects ${revision} @@ -16,8 +16,8 @@ - io.gitee.yunjiao-source - spring-boot-starter-querydsl-jpa + io.gitee.yunjiao-source.spring-boot + starter-querydsl-jpa diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/DataInitCommandLineRunner.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/DataInitCommandLineRunner.java similarity index 89% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/DataInitCommandLineRunner.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/DataInitCommandLineRunner.java index df894f67ce4465f98aa1964b6d27df69bb52486f..eefa6a723c878e584b8e3c6cb4103374644dc6ad 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/DataInitCommandLineRunner.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/DataInitCommandLineRunner.java @@ -1,9 +1,9 @@ -package io.yunjiao.project.rql; +package yunjiao.springboot.project.rql; -import io.yunjiao.project.rql.persistence.dao.MyUserRepository; -import io.yunjiao.project.rql.persistence.dao.UserRepository; -import io.yunjiao.project.rql.persistence.model.MyUser; -import io.yunjiao.project.rql.persistence.model.User; +import yunjiao.springboot.project.rql.persistence.dao.MyUserRepository; +import yunjiao.springboot.project.rql.persistence.dao.UserRepository; +import yunjiao.springboot.project.rql.persistence.model.MyUser; +import yunjiao.springboot.project.rql.persistence.model.User; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/RqlProjectApplication.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/RqlProjectApplication.java similarity index 88% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/RqlProjectApplication.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/RqlProjectApplication.java index 596065ac90fc6962af5cc4a0ae53bf9a8ebcc062..75996633e55213199dbad603d86811d03875f08c 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/RqlProjectApplication.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/RqlProjectApplication.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql; +package yunjiao.springboot.project.rql; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/GenericSpecificationsBuilder.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/GenericSpecificationsBuilder.java similarity index 94% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/GenericSpecificationsBuilder.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/GenericSpecificationsBuilder.java index ae97afa4b33ed70562af062913f3bc962ab0b4d3..4c433205cb48cb4cd8c8ee4485f87e87b062e9b4 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/GenericSpecificationsBuilder.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/GenericSpecificationsBuilder.java @@ -1,7 +1,7 @@ -package io.yunjiao.project.rql.persistence.dao; +package yunjiao.springboot.project.rql.persistence.dao; -import io.yunjiao.project.rql.web.util.SearchOperation; -import io.yunjiao.project.rql.web.util.SpecSearchCriteria; +import yunjiao.springboot.project.rql.web.util.SearchOperation; +import yunjiao.springboot.project.rql.web.util.SpecSearchCriteria; import org.springframework.data.jpa.domain.Specification; import java.util.*; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/MyUserPredicate.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/MyUserPredicate.java similarity index 89% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/MyUserPredicate.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/MyUserPredicate.java index 2fcf487cec0a7237d689ee881aadc6051dc73ca7..2947097228431faf1cf90508b750a1df8e1e0556 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/MyUserPredicate.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/MyUserPredicate.java @@ -1,11 +1,11 @@ -package io.yunjiao.project.rql.persistence.dao; +package yunjiao.springboot.project.rql.persistence.dao; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.NumberPath; import com.querydsl.core.types.dsl.PathBuilder; import com.querydsl.core.types.dsl.StringPath; -import io.yunjiao.project.rql.persistence.model.MyUser; -import io.yunjiao.project.rql.web.util.SearchCriteria; +import yunjiao.springboot.project.rql.persistence.model.MyUser; +import yunjiao.springboot.project.rql.web.util.SearchCriteria; import lombok.Getter; import lombok.Setter; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/MyUserPredicatesBuilder.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/MyUserPredicatesBuilder.java similarity index 93% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/MyUserPredicatesBuilder.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/MyUserPredicatesBuilder.java index cfeae96aed288bf9135eac6c561bbb9cee1684fe..af40ca679e096fcfcb247da585c09f8f4dd60802 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/MyUserPredicatesBuilder.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/MyUserPredicatesBuilder.java @@ -1,8 +1,8 @@ -package io.yunjiao.project.rql.persistence.dao; +package yunjiao.springboot.project.rql.persistence.dao; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.Expressions; -import io.yunjiao.project.rql.web.util.SearchCriteria; +import yunjiao.springboot.project.rql.web.util.SearchCriteria; import org.springframework.lang.NonNull; import java.util.ArrayList; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/MyUserRepository.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/MyUserRepository.java similarity index 84% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/MyUserRepository.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/MyUserRepository.java index e7eaa6843e28549b8cf2634468347844c21f1a9c..d1175983d1db197cb13bc392594c9329dab551c1 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/MyUserRepository.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/MyUserRepository.java @@ -1,7 +1,6 @@ -package io.yunjiao.project.rql.persistence.dao; +package yunjiao.springboot.project.rql.persistence.dao; -import io.yunjiao.project.rql.persistence.model.MyUser; -import io.yunjiao.project.rql.persistence.model.QMyUser; +import yunjiao.springboot.project.rql.persistence.model.MyUser; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.querydsl.QuerydslPredicateExecutor; import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer; @@ -11,6 +10,7 @@ import org.springframework.data.querydsl.binding.SingleValueBinding; import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.core.types.dsl.StringPath; import org.springframework.stereotype.Repository; +import yunjiao.springboot.project.rql.persistence.model.QMyUser; @Repository public interface MyUserRepository extends JpaRepository, QuerydslPredicateExecutor, QuerydslBinderCustomizer { diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserRepository.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserRepository.java similarity index 82% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserRepository.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserRepository.java index 5ad2170978808807c39a5d8ea01db75f6a371976..a5d7f789d45ad5630eaa59877bcaf1e4dc754eb2 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserRepository.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserRepository.java @@ -1,7 +1,7 @@ -package io.yunjiao.project.rql.persistence.dao; +package yunjiao.springboot.project.rql.persistence.dao; -import io.yunjiao.project.rql.persistence.model.User; -import io.yunjiao.project.rql.web.util.SearchCriteria; +import yunjiao.springboot.project.rql.persistence.model.User; +import yunjiao.springboot.project.rql.web.util.SearchCriteria; import jakarta.persistence.criteria.Predicate; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserSearchQueryCriteriaConsumer.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserSearchQueryCriteriaConsumer.java similarity index 92% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserSearchQueryCriteriaConsumer.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserSearchQueryCriteriaConsumer.java index eb9b1ad1e00768e66b4245cd976a2ea5f8a2a5b1..3b11224659584c09fdea0d2ae61aa0542ab61d16 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserSearchQueryCriteriaConsumer.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserSearchQueryCriteriaConsumer.java @@ -1,6 +1,6 @@ -package io.yunjiao.project.rql.persistence.dao; +package yunjiao.springboot.project.rql.persistence.dao; -import io.yunjiao.project.rql.web.util.SearchCriteria; +import yunjiao.springboot.project.rql.web.util.SearchCriteria; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserSpecification.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserSpecification.java similarity index 66% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserSpecification.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserSpecification.java index 57bcdcd885e0f5d13f64dc21c56b237d4919eb06..bdb20e1847bbf29a96f43b21670cc70d7ad13c63 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserSpecification.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserSpecification.java @@ -1,32 +1,23 @@ -package io.yunjiao.project.rql.persistence.dao; +package yunjiao.springboot.project.rql.persistence.dao; -import io.yunjiao.project.rql.persistence.model.User; -import io.yunjiao.project.rql.web.util.SpecSearchCriteria; +import lombok.Getter; +import yunjiao.springboot.project.rql.persistence.model.User; +import yunjiao.springboot.project.rql.web.util.SpecSearchCriteria; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; import org.springframework.data.jpa.domain.Specification; -public class UserSpecification implements Specification { - - private SpecSearchCriteria criteria; - - public UserSpecification(final SpecSearchCriteria criteria) { - super(); - this.criteria = criteria; - } - - public SpecSearchCriteria getCriteria() { - return criteria; - } +@Getter +public record UserSpecification(SpecSearchCriteria criteria) implements Specification { public static Specification empty() { - return Specification.unrestricted(); + return (root, query, builder) -> null; } - @Override - public Predicate toPredicate(final Root root, final CriteriaQuery query, final CriteriaBuilder builder) { + @Override + public Predicate toPredicate(final Root root, final CriteriaQuery query, final CriteriaBuilder builder) { return switch (criteria.getOperation()) { case EQUALITY -> builder.equal(root.get(criteria.getKey()), criteria.getValue()); case NEGATION -> builder.notEqual(root.get(criteria.getKey()), criteria.getValue()); @@ -38,6 +29,6 @@ public class UserSpecification implements Specification { case CONTAINS -> builder.like(root.get(criteria.getKey()), "%" + criteria.getValue() + "%"); default -> null; }; - } + } } diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserSpecificationsBuilder.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserSpecificationsBuilder.java similarity index 89% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserSpecificationsBuilder.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserSpecificationsBuilder.java index 2a26c49824a30465f1ab87ca59cd6bef6016cf2e..f32672b84fcaade59a688e4b76c7d12c3c1f40ab 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/UserSpecificationsBuilder.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/UserSpecificationsBuilder.java @@ -1,8 +1,8 @@ -package io.yunjiao.project.rql.persistence.dao; +package yunjiao.springboot.project.rql.persistence.dao; -import io.yunjiao.project.rql.persistence.model.User; -import io.yunjiao.project.rql.web.util.SearchOperation; -import io.yunjiao.project.rql.web.util.SpecSearchCriteria; +import yunjiao.springboot.project.rql.persistence.model.User; +import yunjiao.springboot.project.rql.web.util.SearchOperation; +import yunjiao.springboot.project.rql.web.util.SpecSearchCriteria; import org.springframework.data.jpa.domain.Specification; import org.springframework.lang.NonNull; @@ -60,7 +60,7 @@ public final class UserSpecificationsBuilder { } public final UserSpecificationsBuilder with(UserSpecification spec) { - params.add(spec.getCriteria()); + params.add(spec.criteria()); return this; } diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/CustomRsqlVisitor.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/CustomRsqlVisitor.java similarity index 93% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/CustomRsqlVisitor.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/CustomRsqlVisitor.java index 4476965fc4cd60a34d33fc0b2e463ed423aaeb9f..96d335de96ce7b050f3ca88f6a0d9608742ba9ca 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/CustomRsqlVisitor.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/CustomRsqlVisitor.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.persistence.dao.rsql; +package yunjiao.springboot.project.rql.persistence.dao.rsql; import org.springframework.data.jpa.domain.Specification; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/GenericRsqlSpecBuilder.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/GenericRsqlSpecBuilder.java similarity index 96% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/GenericRsqlSpecBuilder.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/GenericRsqlSpecBuilder.java index fdc3c7ea016ec66291716c11ad53ee16149b8bc6..5cbced6bd4d6dc7de398095398badc5a99b30b70 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/GenericRsqlSpecBuilder.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/GenericRsqlSpecBuilder.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.persistence.dao.rsql; +package yunjiao.springboot.project.rql.persistence.dao.rsql; import cz.jirutka.rsql.parser.ast.ComparisonNode; import cz.jirutka.rsql.parser.ast.LogicalNode; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/GenericRsqlSpecification.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/GenericRsqlSpecification.java similarity index 98% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/GenericRsqlSpecification.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/GenericRsqlSpecification.java index c35d7fd090044d5b712fad45c9e3658bd8d02694..6c67f75d382bdfdc97b312dd22c3ac29b7c4d25c 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/GenericRsqlSpecification.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/GenericRsqlSpecification.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.persistence.dao.rsql; +package yunjiao.springboot.project.rql.persistence.dao.rsql; import cz.jirutka.rsql.parser.ast.ComparisonOperator; import jakarta.persistence.criteria.CriteriaBuilder; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/RsqlSearchOperation.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/RsqlSearchOperation.java similarity index 94% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/RsqlSearchOperation.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/RsqlSearchOperation.java index 95102bef94750709e3210dbe5cc3f7d3014c8137..18b4933c1a53245a5cb5398f5cecf6e8a5b06390 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/dao/rsql/RsqlSearchOperation.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/dao/rsql/RsqlSearchOperation.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.persistence.dao.rsql; +package yunjiao.springboot.project.rql.persistence.dao.rsql; import cz.jirutka.rsql.parser.ast.ComparisonOperator; import cz.jirutka.rsql.parser.ast.RSQLOperators; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/model/MyUser.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/model/MyUser.java similarity index 87% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/model/MyUser.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/model/MyUser.java index bfbde779bf5f560cb41684078d14ee79263fcc47..9ca0f340a32f6c875d1b67b04213cf5743c38f58 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/model/MyUser.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/model/MyUser.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.persistence.model; +package yunjiao.springboot.project.rql.persistence.model; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/model/User.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/model/User.java similarity index 84% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/model/User.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/model/User.java index a92c1eb5402f73466f3ad6fb8d77e5caaa0d746f..3648936aeef1b39743d08c4eedbd3964bd9cd00e 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/model/User.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/model/User.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.persistence.model; +package yunjiao.springboot.project.rql.persistence.model; import jakarta.persistence.*; import lombok.Data; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/model/User_.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/model/User_.java similarity index 89% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/model/User_.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/model/User_.java index ca62bce715cb64da7fec5b914f9cfb8b824bb361..d09b02b7deeccaa4425d98d14d6fd1f0dcc1ac1e 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/persistence/model/User_.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/persistence/model/User_.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.persistence.model; +package yunjiao.springboot.project.rql.persistence.model; import jakarta.persistence.metamodel.SingularAttribute; import jakarta.persistence.metamodel.StaticMetamodel; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/controller/UserController.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/controller/UserController.java similarity index 90% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/controller/UserController.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/controller/UserController.java index eb456ff668dfe41cdef90ec5f0f72aa91eb92096..7b6dfe1ac42a8f8e88c0870d089a5301b93ea905 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/controller/UserController.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/controller/UserController.java @@ -1,17 +1,17 @@ -package io.yunjiao.project.rql.web.controller; +package yunjiao.springboot.project.rql.web.controller; import com.google.common.base.Joiner; import com.querydsl.core.types.Predicate; import com.querydsl.core.types.dsl.BooleanExpression; import cz.jirutka.rsql.parser.RSQLParser; import cz.jirutka.rsql.parser.ast.Node; -import io.yunjiao.project.rql.persistence.dao.*; -import io.yunjiao.project.rql.persistence.dao.rsql.CustomRsqlVisitor; -import io.yunjiao.project.rql.persistence.model.MyUser; -import io.yunjiao.project.rql.persistence.model.User; -import io.yunjiao.project.rql.web.util.CriteriaParser; -import io.yunjiao.project.rql.web.util.SearchCriteria; -import io.yunjiao.project.rql.web.util.SearchOperation; +import yunjiao.springboot.project.rql.persistence.dao.*; +import yunjiao.springboot.project.rql.persistence.dao.rsql.CustomRsqlVisitor; +import yunjiao.springboot.project.rql.persistence.model.MyUser; +import yunjiao.springboot.project.rql.persistence.model.User; +import yunjiao.springboot.project.rql.web.util.CriteriaParser; +import yunjiao.springboot.project.rql.web.util.SearchCriteria; +import yunjiao.springboot.project.rql.web.util.SearchOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.querydsl.binding.QuerydslPredicate; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/error/RestResponseEntityExceptionHandler.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/error/RestResponseEntityExceptionHandler.java similarity index 96% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/error/RestResponseEntityExceptionHandler.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/error/RestResponseEntityExceptionHandler.java index 43fb5b5c1d57e3483d996879e883b66d81a7e683..7db25b697e9ed518b498842fee4b3226adcbcecd 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/error/RestResponseEntityExceptionHandler.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/error/RestResponseEntityExceptionHandler.java @@ -1,6 +1,6 @@ -package io.yunjiao.project.rql.web.error; +package yunjiao.springboot.project.rql.web.error; -import io.yunjiao.project.rql.web.exception.MyResourceNotFoundException; +import yunjiao.springboot.project.rql.web.exception.MyResourceNotFoundException; import jakarta.persistence.EntityNotFoundException; import org.hibernate.exception.ConstraintViolationException; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/exception/MyResourceNotFoundException.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/exception/MyResourceNotFoundException.java similarity index 89% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/exception/MyResourceNotFoundException.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/exception/MyResourceNotFoundException.java index 444274db7007b02f12b89ae0328c1e51243e4c3c..a4d28d4809f981d8f779ba762503ce0f4c449b74 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/exception/MyResourceNotFoundException.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/exception/MyResourceNotFoundException.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.web.exception; +package yunjiao.springboot.project.rql.web.exception; public final class MyResourceNotFoundException extends RuntimeException { diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/CriteriaParser.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/CriteriaParser.java similarity index 98% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/CriteriaParser.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/CriteriaParser.java index 8a8f05cd007cca9d06131214311dc76e0842201f..91f4fa58e467374843168a0698922d2da376748c 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/CriteriaParser.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/CriteriaParser.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.web.util; +package yunjiao.springboot.project.rql.web.util; import com.google.common.base.Joiner; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/SearchCriteria.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/SearchCriteria.java similarity index 94% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/SearchCriteria.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/SearchCriteria.java index 05e60e2e798b48011290cf4fb550ab513511dd37..c4544e53aadc08d9d03022834a4163801cbda06e 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/SearchCriteria.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/SearchCriteria.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.web.util; +package yunjiao.springboot.project.rql.web.util; public class SearchCriteria { diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/SearchOperation.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/SearchOperation.java similarity index 95% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/SearchOperation.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/SearchOperation.java index 10233f21ac98095770a2362dfeb8d3ef5bad9b7a..a2f1e9cbaf655a551209f8cb533a5bb1f2d493e4 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/SearchOperation.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/SearchOperation.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.web.util; +package yunjiao.springboot.project.rql.web.util; public enum SearchOperation { EQUALITY, NEGATION, GREATER_THAN, LESS_THAN, LIKE, STARTS_WITH, ENDS_WITH, CONTAINS; diff --git a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/SpecSearchCriteria.java b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/SpecSearchCriteria.java similarity index 97% rename from projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/SpecSearchCriteria.java rename to projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/SpecSearchCriteria.java index 5d804bcd9d8c377d45fb1569db0d0237ab12a202..6d1a025db8fd196447d552c7c362d5989a037413 100644 --- a/projects/rest-query-language/src/main/java/io/yunjiao/project/rql/web/util/SpecSearchCriteria.java +++ b/projects/rest-query-language/src/main/java/yunjiao/springboot/project/rql/web/util/SpecSearchCriteria.java @@ -1,4 +1,4 @@ -package io.yunjiao.project.rql.web.util; +package yunjiao.springboot.project.rql.web.util; public class SpecSearchCriteria { diff --git a/projects/rest-query-language/src/main/resources/application.yml b/projects/rest-query-language/src/main/resources/application.yml index d43db6fb5fb24c6dc00bbfa02548cc0b60530051..87bfd5109c9b7b21728d864b57c96f7e771b696e 100644 --- a/projects/rest-query-language/src/main/resources/application.yml +++ b/projects/rest-query-language/src/main/resources/application.yml @@ -18,5 +18,5 @@ logging: root: info org.springframework.boot.autoconfigure: info org.springframework.context: debug - io.yunjiao: debug + yunjiao.springboot: debug diff --git a/projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/JPACriteriaQueryIntegrationTest.java b/projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/JPACriteriaQueryIntegrationTest.java similarity index 92% rename from projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/JPACriteriaQueryIntegrationTest.java rename to projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/JPACriteriaQueryIntegrationTest.java index 0ca089da2da9d193e487da99d868bf6423a36061..e2e97e0cf37139850bdae0cf7ca41f7ef9b9994e 100644 --- a/projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/JPACriteriaQueryIntegrationTest.java +++ b/projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/JPACriteriaQueryIntegrationTest.java @@ -1,8 +1,8 @@ -package io.yunjiao.project.rql.persistence.query; +package yunjiao.springboot.project.rql.persistence.query; -import io.yunjiao.project.rql.persistence.dao.UserRepository; -import io.yunjiao.project.rql.persistence.model.User; -import io.yunjiao.project.rql.web.util.SearchCriteria; +import yunjiao.springboot.project.rql.persistence.dao.UserRepository; +import yunjiao.springboot.project.rql.persistence.model.User; +import yunjiao.springboot.project.rql.web.util.SearchCriteria; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/JPAQuerydslIntegrationTest.java b/projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/JPAQuerydslIntegrationTest.java similarity index 91% rename from projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/JPAQuerydslIntegrationTest.java rename to projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/JPAQuerydslIntegrationTest.java index e8cbc3f2445057dab3f936bb8b1e9042d5a043a6..a39fe6bc00473d23c091e96b1c7133b6ae1f9c08 100644 --- a/projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/JPAQuerydslIntegrationTest.java +++ b/projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/JPAQuerydslIntegrationTest.java @@ -1,8 +1,8 @@ -package io.yunjiao.project.rql.persistence.query; +package yunjiao.springboot.project.rql.persistence.query; -import io.yunjiao.project.rql.persistence.dao.MyUserPredicatesBuilder; -import io.yunjiao.project.rql.persistence.dao.MyUserRepository; -import io.yunjiao.project.rql.persistence.model.MyUser; +import yunjiao.springboot.project.rql.persistence.dao.MyUserPredicatesBuilder; +import yunjiao.springboot.project.rql.persistence.dao.MyUserRepository; +import yunjiao.springboot.project.rql.persistence.model.MyUser; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/JPASpecificationIntegrationTest.java b/projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/JPASpecificationIntegrationTest.java similarity index 90% rename from projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/JPASpecificationIntegrationTest.java rename to projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/JPASpecificationIntegrationTest.java index 536ce28087a8e7a70255133cced84f7cf2b9e7d6..8e3c55a1389d79e37c1ed1a17854af8b75513d43 100644 --- a/projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/JPASpecificationIntegrationTest.java +++ b/projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/JPASpecificationIntegrationTest.java @@ -1,13 +1,13 @@ -package io.yunjiao.project.rql.persistence.query; - -import io.yunjiao.project.rql.persistence.dao.GenericSpecificationsBuilder; -import io.yunjiao.project.rql.persistence.dao.UserRepository; -import io.yunjiao.project.rql.persistence.dao.UserSpecification; -import io.yunjiao.project.rql.persistence.dao.UserSpecificationsBuilder; -import io.yunjiao.project.rql.persistence.model.User; -import io.yunjiao.project.rql.web.util.CriteriaParser; -import io.yunjiao.project.rql.web.util.SearchOperation; -import io.yunjiao.project.rql.web.util.SpecSearchCriteria; +package yunjiao.springboot.project.rql.persistence.query; + +import yunjiao.springboot.project.rql.persistence.dao.GenericSpecificationsBuilder; +import yunjiao.springboot.project.rql.persistence.dao.UserRepository; +import yunjiao.springboot.project.rql.persistence.dao.UserSpecification; +import yunjiao.springboot.project.rql.persistence.dao.UserSpecificationsBuilder; +import yunjiao.springboot.project.rql.persistence.model.User; +import yunjiao.springboot.project.rql.web.util.CriteriaParser; +import yunjiao.springboot.project.rql.web.util.SearchOperation; +import yunjiao.springboot.project.rql.web.util.SpecSearchCriteria; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/RsqlIntegrationTest.java b/projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/RsqlIntegrationTest.java similarity index 92% rename from projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/RsqlIntegrationTest.java rename to projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/RsqlIntegrationTest.java index 5502130fd2c4df1e35e329096d4e811bf80a8aad..b6e9b2a2b65ec21ab7c831f9e53344e5a5b2d2e7 100644 --- a/projects/rest-query-language/src/test/java/io/yunjiao/project/rql/persistence/query/RsqlIntegrationTest.java +++ b/projects/rest-query-language/src/test/java/yunjiao/springboot/project/rql/persistence/query/RsqlIntegrationTest.java @@ -1,10 +1,10 @@ -package io.yunjiao.project.rql.persistence.query; +package yunjiao.springboot.project.rql.persistence.query; import cz.jirutka.rsql.parser.RSQLParser; import cz.jirutka.rsql.parser.ast.Node; -import io.yunjiao.project.rql.persistence.dao.UserRepository; -import io.yunjiao.project.rql.persistence.dao.rsql.CustomRsqlVisitor; -import io.yunjiao.project.rql.persistence.model.User; +import yunjiao.springboot.project.rql.persistence.dao.UserRepository; +import yunjiao.springboot.project.rql.persistence.dao.rsql.CustomRsqlVisitor; +import yunjiao.springboot.project.rql.persistence.model.User; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot-starter-hutool/README.md b/spring-boot-starter-hutool/README.md deleted file mode 100644 index 32296b9557163a826dd2bb752e994ebccc1cc483..0000000000000000000000000000000000000000 --- a/spring-boot-starter-hutool/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# spring-boot-starter-hutool - -基于Hutool框架的自动配置Starter - - -## maven - -在`pom.xml`中添加依赖 - -```xml - - io.gitee.yunjiao-source - spring-boot-starter-hutool - -``` - -## 使用指南 - -### Snowflake(Twitter的Snowflake 算法) - -支持`Long`类型及字符类型。默认workerId=1,datacenterId=2, 如需支持分布式, -请设置系统环境变量:SNOWFLAKE_WORKER_ID 与 SNOWFLAKE_DATACENTER_ID - -自动注入 -```java - @Autowired - private Snowflake snowflake; - - @Override - public void run(String... args) throws Exception { - log.info("Snowflake = {}", snowflake.nextId()); - } -``` - - -关闭配置 - -```yaml -spring: - hutool: - snowflake: false # 默认true -``` - - - diff --git a/spring-boot-starter-querydsl-jpa/README.md b/spring-boot-starter-querydsl-jpa/README.md deleted file mode 100644 index 8122ff15c128394aea642f3cfff094711ba7d2b1..0000000000000000000000000000000000000000 --- a/spring-boot-starter-querydsl-jpa/README.md +++ /dev/null @@ -1,364 +0,0 @@ -# spring-boot-starter-querydsl-jpa - -[QueryDSL](http://querydsl.com/) 是一个框架,可以构建静态类型的 SQL 类查询。无需将查询编写为内联字符串或将它们外部化为 XML 文件, -它们可以通过 `Querydsl` 之类的流畅 API 构建。 - -本项目集成`QueryDSL JPA`框架,实现`JPAQueryFactory`实例自动配置,也可以自由的自定义配置。提供`JPAQueryRepositorySupport`抽象类, -让CURD,分页查询更方便。 - - -## 使用指南 - -本指南使用`maven`构建工具 - -### 创建新项目 - -创建一个新项目,在pom.xml中定义: - -```text -...... - - - io.gitee.yunjiao-source - spring-boot-examples - ${你需要的版本} - - -...... - - - - io.gitee.yunjiao-source - spring-boot-starter-querydsl-jpa - - - - com.querydsl - querydsl-apt - jakarta - provided - - - - -...... -``` - -其他的依赖包请按需添加 - -### JPA的实体类 - -创建用户及订单的实体类,是一对多的关系 - -`Order.java` - -```java -@Data -@Entity -@Table(name = "orders") -public class Order { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ToString.Exclude - @ManyToOne(fetch = FetchType.LAZY) // 推荐懒加载 - @JoinColumn(name = "user_id") // 指定外键列名 - private User user; - - private String status; - - private BigDecimal amount; - - @Column(name="transaction_time") - private Date transactionTime; -} - -``` - -`User.java` - -```java -@Data -@Entity -@Table(name = "users") -public class User { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String name; - - private Integer age; - - private String email; - - @Column(name="birth_date") - private Date birthDate; - - @Column(name="created_at") - private Date createdAt; - - @ToString.Exclude - @OneToMany( - mappedBy = "user", // - cascade = CascadeType.ALL, // 级联所有操作(保存/更新/删除) - orphanRemoval = true // 删除孤儿数据(子实体与父实体断开时自动删除) - ) - private List orders = new ArrayList<>(); -} -``` - -创建完成后,执行编译命令`mvn clean compile`后,会在`target/generated-sources`目录 -下生成`QOrder`, `QUser`两个类 - -### 条件查询 - -`Spring boot` 框架中提供`Specification`接口,支持复杂查询,条件复用等功能。本框架中也提供`QSpecification` -接口 - -`UserSpec.java` - -```java -public final class UserSpec { - private static final QUser qUser = QUser.user; - - public static QSpecification idEq(Long id) { - return builder -> qUser.id.eq(id); - } - - public static QSpecification nameLike(String name) { - return builder -> qUser.name.like(name); - } - - public static QSpecification nameEq(String name) { - return builder -> qUser.name.eq(name); - } - - public static QSpecification ageGoe(Integer age) { - return builder -> qUser.age.goe(age); - } - public static QSpecification birthDate(Date birthDate) { - return builder -> qUser.birthDate.goe(birthDate); - } - -} -``` - -为了更方便的使用上面的条件,可以创建一个类,生成条件 - -`UserQuery.java` - -```java -Getter -@Setter -@Accessors(fluent = true, chain = true) -public class UserQuery { - private final QUser qUser = QUser.user; - private String name; - private Integer minAge; - private Boolean orderByCreateAt; - private Boolean orderByAge; - - - public QSpecification buildQSpecification() { - QSpecification spec = QSpecification.where(null); - if (StringUtils.hasText(name)) { - spec = spec.and(nameLike(name)); - } - if (Objects.nonNull(minAge)) { - spec = spec.and(ageGoe(minAge)); - } - return spec; - } - - public QSort buildQsort() { - QSort sort = new QSort(); - if (Objects.nonNull(orderByAge)) { - sort = sort.and(orderBy(orderByAge, qUser.age)); - } - if (Objects.nonNull(orderByCreateAt)) { - sort = sort.and(orderBy(orderByCreateAt, qUser.createdAt)); - } - return sort; - } -} -``` - -### 仓库 - -仓库类需要继承`JPAQueryRepositorySupport` - -`UserJPARepository.java` - -```java -@Repository -public class UserJPARepository extends JPAQueryRepositorySupport { - private static final QUser qUser = QUser.user; - private static final QOrder qOrder = QOrder.order; - - @Autowired - private EntityManager entityManager; - - - public UserJPARepository() { - super(qUser); - } - - // 主键查询 - public User findById(Long id) { - JPAQuery query = selectFrom(qUser) - .where(qUser.id.eq(id)); - return getCurdExecutor().findMustOne(query); - } - - public User findOrderById(Long id) { - JPAQuery query = selectFrom(qUser) - .leftJoin(qUser.orders, qOrder).fetchJoin() - .where(qUser.id.eq(id)); - return getCurdExecutor().findMustOne(query); - } - - // 使用名称查询唯一用户 - public Optional findSingleByName(String name) { - JPAQuery query = selectFrom(qUser); - return getCurdExecutor().findOnlyOne(query, nameEq(name)); - } - - // 多条件,排序查询 - public List findList(String name, Integer age, Date birthDate) { - JPAQuery query = selectFrom(qUser); - QSpecification spec = nameLike(name).and(ageGoe(age), birthDate(birthDate)); - QSort sort = QSort.by(qUser.age.asc(), qUser.birthDate.desc()); - return getCurdExecutor().findList(query, spec, sort); - } - - // 分页查询, 使用QPageRequest对象 - public Page findQPage(Integer age) { - JPAQuery countQuery = select(qUser.count()).from(qUser); - JPAQuery query = selectFrom(qUser); - QSort sort = QSort.by(qUser.age.desc()); - return getCurdExecutor().findPage(countQuery, query, QPageRequest.of(0, 5, sort), ageGoe(age)); - } - - // 分页查询, 使用PageRequest对象 - public Page findPage(Integer age) { - JPAQuery query = selectFrom(qUser); - QSort sort = QSort.by(qUser.age.asc()); - return findPage(query, PageRequest.of(0, 5, sort), ageGoe(age)); - } - - // 关联查询:查询已完成订单的用户信息 - public List findUserByOrderStatus() { - JPAQuery query = selectFrom(qUser) - .distinct() - .innerJoin(qUser.orders, qOrder) - .where(qOrder.status.eq("completed")); - return getCurdExecutor().findList(query); - } - - // 插入数据示例 - public long insertUser(User user) { - return insert(qUser) - .columns(qUser.name, qUser.age) - .values(user.getName(), user.getAge()) - .execute(); - } - - // 更新数据 - public long updateName(Long id, String newName) { - JPAUpdateClause update = update(qUser) - .set(qUser.name, newName); - return getCurdExecutor().update(update, idEq(id)); - } - - // 批量插入 - @Transactional(rollbackFor = Exception.class) - public void insertUserBatch(List users) { - long count = 0; - for (User user : users) { - JPAInsertClause insert = insert(qUser) - .columns(qUser.name, qUser.age); - insert.values(user.getName(), user.getAge()); - count += insert.execute(); - } - System.out.println("插入行数 " + count); - } - - // 模拟大量删除 - @Transactional(rollbackFor = Exception.class) - public void deleteUser(Integer age) { - final long maxLimit = 99L; - - // 查询 - JPAQuery queryClause = select(qUser.id).from(qUser).limit(maxLimit); - getCurdExecutor().applaySpecification(ageGoe(age), queryClause); - - while (true) { - List userIdList = queryClause.fetch(); - if (userIdList.isEmpty()) { - break; - } - - // 删除语句 - JPADeleteClause deleteClause = delete(qUser).where(qUser.id.in(userIdList)); - // 执行 - long count = deleteClause.execute(); - System.out.println("分批删除完成,影响行数: " + count); - if (count < maxLimit) { - break; - } - } - - } - - // 使用查询对象 - public List findByQuery(UserQuery query) { - return getCurdExecutor().findList(selectFrom(qUser), - query.buildQSpecification(), - query.buildQsort()); - } -} -``` - -### 服务 - -`UserJPAService.java` - -```java -@Getter -@Service -@RequiredArgsConstructor -public class UserJPAService { - private final UserJPARepository userJPARepository; - - @Transactional - public void insertUserBatch() { - List userList = IntStream.range(0, 1000).mapToObj(i -> { - User user = new User(); - user.setName("李四-" + i); - user.setAge(102); - - return user; - }).toList(); - userJPARepository.insertUserBatch(userList); - } - - @Transactional - public void deleteUserBatch() { - userJPARepository.deleteUser(101); - } - - public List findByName(String name) { - UserQuery query = new UserQuery().name(name) - .orderByAge(true); - return userJPARepository.findByQuery(query); - } - -} - -``` - -全部代码完成。详细的,可运行的代码请参考示例项目`spring-boot-examples/spring-boot-example-querydsl-jpa` - - diff --git a/spring-boot-starter-querydsl-sql/README.md b/spring-boot-starter-querydsl-sql/README.md deleted file mode 100644 index 5448590b1deba98ac5090ef3cf166b00ded2ad5b..0000000000000000000000000000000000000000 --- a/spring-boot-starter-querydsl-sql/README.md +++ /dev/null @@ -1,370 +0,0 @@ -# spring-boot-starter-querydsl-sql - -[QueryDSL](http://querydsl.com/) 是一个框架,可以构建静态类型的 SQL 类查询。无需将查询编写为内联字符串或将它们外部化为 XML 文件, -它们可以通过 `Querydsl` 之类的流畅 API 构建。 - -本项目集成`QueryDSL SQL`框架,实现`SQLQueryFactory`实例自动配置,也可以自由的自定义配置。提供`SQLQueryRepositorySupport`抽象类, -让CURD,分页查询更方便。 - - -## 使用指南 - -本指南使用`maven`构建工具 - -### 创建新项目 - -创建一个新项目,在pom.xml中定义: - -```text -...... - - - io.gitee.yunjiao-source - spring-boot-examples - ${你需要的版本} - - -...... - - - - io.gitee.yunjiao-source - spring-boot-starter-querydsl-sql - - - - com.querydsl - querydsl-sql-codegen - provided - - - - -...... - - - - - com.querydsl - querydsl-maven-plugin - - - - export - - - - - - com.mysql.cj.jdbc.Driver - jdbc:mysql://localhost:3306/yunjiao?userSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8 - system - system - io.yunjiao.example.querydsl - ${project.basedir}/target/generated-sources/java - - - - - com.mysql - mysql-connector-j - 9.2.0 - - - - - - -...... -``` - -其他的依赖包请按需添加 - -### 自定义SQLQueryFactory - -创建一个配置Bean -```java - @Bean - SQLQueryFactoryConfigurer sqlQueryFactoryConfigurer() { - return sqlQueryFactory -> { - com.querydsl.sql.Configuration config = sqlQueryFactory.getConfiguration(); - log.info("配置:Configuration={}", config); - - SQLTemplates template = config.getTemplates(); - log.info("配置:SQLTemplates={}", template); - }; - } -``` - -### 实体类 - -创建用户及订单的实体类,是一对多的关系 - -`User.java` - -```java -@Data -public class User { - private Long id; - private String name; - private Integer age; - private String email; - private String birthData; - private Date createAt; -} - -``` - -创建完成后,执行编译命令`mvn clean compile`后,会在`target/generated-sources`目录 -下生成`QOrder`, `QUser`两个类。 - -注意:数据库中的所有表都会被创建Q类 - -### 条件查询 - -`Spring boot` 框架中提供`Specification`接口,支持复杂查询,条件复用等功能。本框架中也提供`QSpecification` -接口 - -`UserSpec.java` - -```java -public final class UserSpec { - private static final QUser qUser = QUser.user; - - public static QSpecification idEq(Long id) { - return builder -> qUser.id.eq(id); - } - - public static QSpecification nameLike(String name) { - return builder -> qUser.name.like(name); - } - - public static QSpecification nameEq(String name) { - return builder -> qUser.name.eq(name); - } - - public static QSpecification ageGoe(Integer age) { - return builder -> qUser.age.goe(age); - } - public static QSpecification birthDate(Date birthDate) { - return builder -> qUser.birthDate.goe(birthDate); - } - -} -``` - -为了更方便的使用上面的条件,可以创建一个类,生成条件 - -`UserQuery.java` - -```java -@Getter -@Setter -@Accessors(fluent = true, chain = true) -public class UserQuery { - private final QUser qUser = QUser.user; - private String name; - private Integer minAge; - private Boolean orderByCreateAt; - private Boolean orderByAge; - - - public QSpecification buildQSpecification() { - QSpecification spec = QSpecification.where(null); - if (StringUtils.hasText(name)) { - spec = spec.and(nameLike(name)); - } - if (Objects.nonNull(minAge)) { - spec = spec.and(ageGoe(minAge)); - } - return spec; - } - - public QSort buildQsort() { - QSort sort = new QSort(); - if (Objects.nonNull(orderByAge)) { - sort = sort.and(orderBy(orderByAge, qUser.age)); - } - if (Objects.nonNull(orderByCreateAt)) { - sort = sort.and(orderBy(orderByCreateAt, qUser.createdAt)); - } - return sort; - } -} - -``` - -### 仓库 - -仓库类需要继承`SQLQueryRepositorySupport` - -`UserSQLRepository.java` - -```java -@Repository -@Transactional -public class UserSQLRepository extends SQLQueryRepositorySupport { - private static final QUser qUser = QUser.user; - private static final QOrder qOrder = QOrder.order; - - - public UserSQLRepository() { - super(qUser); - } - - // 主键查询 - public User findById(Long id) { - SQLQuery query = select(Projections.bean(User.class, qUser.all())) - .from(qUser) - .where(qUser.id.eq(id)); - return getCurdExecutor().findMustOne(query); - } - - - // 使用名称查询唯一用户 - public Optional findSingleByName(String name) { - SQLQuery query = select(Projections.bean(User.class, qUser.all())) - .from(qUser); - return getCurdExecutor().findOnlyOne(query, nameEq(name)); - } - - // 多条件,排序查询 - public List findList(String name, Integer age, Date birthDate) { - SQLQuery query = select(Projections.bean(User.class, qUser.all())) - .from(qUser); - QSpecification spec = nameLike(name).and(ageGoe(age), birthDate(birthDate)); - QSort sort = QSort.by(qUser.age.asc(), qUser.birthDate.desc()); - return getCurdExecutor().findList(query, spec, sort); - } - - // 分页查询, 使用QPageRequest对象 - public Page findQPage(Integer age) { - SQLQuery query = select(Projections.bean(User.class, qUser.all())) - .from(qUser); - QSort sort = QSort.by(qUser.age.desc()); - return getCurdExecutor().findPage(query, QPageRequest.of(0, 5, sort), ageGoe(age)); - } - - // 分页查询, 使用PageRequest对象 - public Page findPage(Integer age) { - SQLQuery query = select(Projections.bean(User.class, qUser.all())) - .from(qUser); - QSort sort = QSort.by(qUser.age.asc()); - return findPage(query, PageRequest.of(0, 5, sort), ageGoe(age)); - } - - // 关联查询:查询已完成订单的用户信息 - public List findUserByOrderStatus() { - SQLQuery query = select(Projections.bean(User.class, qUser.all())) - .distinct() - .from(qUser) - .innerJoin(qUser.order, qOrder) - .where(qOrder.status.eq("completed")); - return getCurdExecutor().findList(query); - } - - // 插入数据示例 - public Long insertUser(User user) { - return insert(qUser) - .set(qUser.name, user.getName()) - .set(qUser.age, user.getAge()) - .executeWithKey(qUser.id); // 返回自增ID - } - - // 更新数据 - public long updateName(Long id, String newName) { - SQLUpdateClause update = update(qUser) - .set(qUser.name, newName); - return getCurdExecutor().update(update, idEq(id)); - } - - // 批量插入 - @Transactional(rollbackFor = Exception.class) - public void insertUserBatch(List users) { - List> batches = Lists.partition(users, 100); - batches.forEach(usersSub -> { - SQLInsertClause insert = insertBatch(qUser); - for (User user : usersSub) { - insert.populate(user) - .addBatch(); - } - - // 执行批处理并获取影响行数 - long batchResults = insert.execute(); - System.out.println("分批插入完成,影响行数: " + batchResults); - }); - } - - // 模拟大量删除 - @Transactional(rollbackFor = Exception.class) - public void deleteUser(Integer age) { - final long maxLimit = 99L; - - // 语句 - SQLDeleteClause delete = delete(qUser).limit(maxLimit); - // 添加条件 - getCurdExecutor().applaySpecification(ageGoe(age), delete); - while (true) { - // 执行 - long count = delete.execute(); - System.out.println("分批删除完成,影响行数: " + count); - if (count < maxLimit) { - break; - } - } - - } - - // 使用查询对象 - public List findByQuery(UserQuery query) { - return getCurdExecutor().findList(select(Projections.bean(User.class, qUser.all())).from(qUser), - query.buildQSpecification(), - query.buildQsort()); - } - - -} -``` - -### 服务 - -`UserSQLService.java` - -```java -@Getter -@Service -@RequiredArgsConstructor -public class UserSQLService { - private final UserSQLRepository userSQLRepository; - - @Transactional - public void insertUserBatch() { - List userList = IntStream.range(0, 1000).mapToObj(i -> { - User user = new User(); - user.setName("李四-" + i); - user.setAge(102); - - return user; - }).toList(); - userSQLRepository.insertUserBatch(userList); - } - - @Transactional - public void deleteUserBatch() { - userSQLRepository.deleteUser(101); - } - - public List findByName(String name) { - UserQuery query = new UserQuery().name(name) - .orderByAge(true); - return userSQLRepository.findByQuery(query); - } - -} - - -``` - -全部代码完成。详细的,可运行的代码请参考示例项目`spring-boot-examples/spring-boot-example-querydsl-sql` - - diff --git a/spring-boot-starter-parent/pom.xml b/starter-parent/pom.xml similarity index 96% rename from spring-boot-starter-parent/pom.xml rename to starter-parent/pom.xml index 95de29173aaacde44bcde2f31b51247ac5896947..0aab6f07a64936efe82a5df23a47851bde3935a4 100644 --- a/spring-boot-starter-parent/pom.xml +++ b/starter-parent/pom.xml @@ -5,14 +5,14 @@ org.springframework.boot spring-boot-starter-parent - 3.5.4 + 3.0.13 4.0.0 - io.gitee.yunjiao-source - spring-boot-starter-parent - 3.5.x.2 + io.gitee.yunjiao-source.spring-boot + starter-parent + 0.3.0 pom Spring Boot :: Starter Parent 启动器项目,方便用户开发 @@ -59,7 +59,7 @@ - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot dependencies ${yunjiao-spring-boot.version} pom diff --git a/spring-boot-starter-hutool/pom.xml b/starters/pom.xml similarity index 56% rename from spring-boot-starter-hutool/pom.xml rename to starters/pom.xml index d256509e25021738fc2de8e9c85278f18f9ed2c8..c488c8777b51a3879f0189ad1918d7e7c8843a2b 100644 --- a/spring-boot-starter-hutool/pom.xml +++ b/starters/pom.xml @@ -3,32 +3,31 @@ 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"> - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot dependencies ${revision} ../dependencies/pom.xml 4.0.0 - spring-boot-starter-hutool - jar - Spring Boot :: Starter Hutool - 基于Hutool框架的 启动器 + starters + pom + Spring Boot :: Starters + Starters启动器 + + + starter-id + starter-querydsl-sql + starter-querydsl-jpa + starter-apijson-fastjson2 + starter-apijson-gson + starter-captcha + org.springframework.boot spring-boot-starter - - io.gitee.yunjiao-source - autoconfigure - - - cn.hutool - hutool-core - - - \ No newline at end of file diff --git a/spring-boot-starter-apijson-fastjson2/pom.xml b/starters/starter-apijson-fastjson2/pom.xml similarity index 64% rename from spring-boot-starter-apijson-fastjson2/pom.xml rename to starters/starter-apijson-fastjson2/pom.xml index 626684947a0179a29b570571e9523630b52633d9..8fd1253a1470234409738c9d1d0e26223f422cc5 100644 --- a/spring-boot-starter-apijson-fastjson2/pom.xml +++ b/starters/starter-apijson-fastjson2/pom.xml @@ -3,30 +3,24 @@ 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"> - io.gitee.yunjiao-source - dependencies + io.gitee.yunjiao-source.spring-boot + starters ${revision} - ../dependencies/pom.xml 4.0.0 - spring-boot-starter-apijson-fastjson2 + starter-apijson-fastjson2 jar - Spring Boot :: Starter APIJSON Fastjson2 + Starter :: APIJSON Fastjson2 APIJSON Fastjson2 启动器 - org.springframework.boot - spring-boot-starter - - - - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot autoconfigure - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extension-apijson diff --git a/spring-boot-starter-apijson-gson/pom.xml b/starters/starter-apijson-gson/pom.xml similarity index 64% rename from spring-boot-starter-apijson-gson/pom.xml rename to starters/starter-apijson-gson/pom.xml index f2fa11ee62863999f68e19a3d152ccb246543e45..8eeee184a9201651af63fc83ecf9d1e1a999000d 100644 --- a/spring-boot-starter-apijson-gson/pom.xml +++ b/starters/starter-apijson-gson/pom.xml @@ -3,30 +3,24 @@ 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"> - io.gitee.yunjiao-source - dependencies + io.gitee.yunjiao-source.spring-boot + starters ${revision} - ../dependencies/pom.xml 4.0.0 - spring-boot-starter-apijson-gson + starter-apijson-gson jar - Spring Boot :: Starter APIJSON Gson + Starter :: APIJSON Gson APIJSON Gson 启动器 - org.springframework.boot - spring-boot-starter - - - - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot autoconfigure - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extension-apijson diff --git a/starters/starter-captcha/pom.xml b/starters/starter-captcha/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..c4188829a9938fec52854073fa4dcd542c1251be --- /dev/null +++ b/starters/starter-captcha/pom.xml @@ -0,0 +1,29 @@ + + + + io.gitee.yunjiao-source.spring-boot + starters + ${revision} + + 4.0.0 + + starter-captcha + jar + Starter :: Captcha + 验证码 启动器 + + + + io.gitee.yunjiao-source.spring-boot + autoconfigure + + + io.gitee.yunjiao-source.spring-boot + extension-captcha + + + + + \ No newline at end of file diff --git a/starters/starter-id/pom.xml b/starters/starter-id/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..5d2d6d3c23c791de3dea0718c2b838603ad1204b --- /dev/null +++ b/starters/starter-id/pom.xml @@ -0,0 +1,29 @@ + + + + io.gitee.yunjiao-source.spring-boot + starters + ${revision} + + 4.0.0 + + starter-id + jar + Starter :: Id + Id(身份标识号) 启动器 + + + + io.gitee.yunjiao-source.spring-boot + autoconfigure + + + io.gitee.yunjiao-source.spring-boot + extension-id + + + + + \ No newline at end of file diff --git a/spring-boot-starter-querydsl-jpa/pom.xml b/starters/starter-querydsl-jpa/pom.xml similarity index 65% rename from spring-boot-starter-querydsl-jpa/pom.xml rename to starters/starter-querydsl-jpa/pom.xml index 0548de73e5f29d13d42ce10b6785b0ed55402383..79658d7a95a1889c86ebff7678dbec2afd5e605b 100644 --- a/spring-boot-starter-querydsl-jpa/pom.xml +++ b/starters/starter-querydsl-jpa/pom.xml @@ -3,34 +3,29 @@ 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"> - io.gitee.yunjiao-source - dependencies + io.gitee.yunjiao-source.spring-boot + starters ${revision} - ../dependencies/pom.xml 4.0.0 - spring-boot-starter-querydsl-jpa + starter-querydsl-jpa jar - Spring Boot :: Starter QueryDSL JPA + Starter :: QueryDSL JPA QueryDSL JPA 启动器 - - org.springframework.boot - spring-boot-starter - org.springframework.boot spring-boot-starter-data-jpa - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot autoconfigure - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extension-querydsl diff --git a/spring-boot-starter-querydsl-sql/pom.xml b/starters/starter-querydsl-sql/pom.xml similarity index 67% rename from spring-boot-starter-querydsl-sql/pom.xml rename to starters/starter-querydsl-sql/pom.xml index 5ccb3be71eb55d6cfd46206c58e28830605a9f73..85cc3fc02f5a841de4ad2158f1219e555c008eae 100644 --- a/spring-boot-starter-querydsl-sql/pom.xml +++ b/starters/starter-querydsl-sql/pom.xml @@ -3,29 +3,24 @@ 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"> - io.gitee.yunjiao-source - dependencies + io.gitee.yunjiao-source.spring-boot + starters ${revision} - ../dependencies/pom.xml 4.0.0 - spring-boot-starter-querydsl-sql + starter-querydsl-sql jar - Spring Boot :: Starter QueryDSL SQL + Starter :: QueryDSL SQL QueryDSL SQL 启动器 - org.springframework.boot - spring-boot-starter - - - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot autoconfigure - io.gitee.yunjiao-source + io.gitee.yunjiao-source.spring-boot extension-querydsl