组件编码
hzero-starter-core
一、简介
1.1 概述
该组件主要针对技术开发中进行技术支持,提供一些通用的技术开发支持功能,减少重复造轮子。定义了基础实现类,异常封装,常用工具等。
1.2 组件坐标
<dependency>
<groupId>org.hzero.starter</groupId>
<artifactId>hzero-starter-core</artifactId>
<version>${hzero.starter.version}</version>
</dependency>
二、组件功能
2.1 base
base 包主要定义了一些基础常量、BaseController 等。
-
BaseController
:提供了校验单个对象和集合元素的方法
validObject
、validList
,只需在 Controller 接口方法里使用这些方法即可对@NotBlank
、@Size
、@NotNull
等常用hibernate-validator
包的校验注解进行校验。
提供了getMessage
、getExceptionResponse
、locale
等与返回消息相关的便捷方法使用。 -
BaseConstants
:定义了常用的字段常量:
Long DEFAULT_TENANT_ID = 0L; String PAGE = "0"; String SIZE = "10"; String FIELD_BODY = "body"; String FIELD_CONTENT = "content"; String FIELD_MSG = "message"; String FIELD_FAILED = "failed";
在
Pattern
接口定义了各种格式的日期时间格式常量:interface Pattern { // // 常规模式 // ---------------------------------------------------------------------------------------------------- String DATE = "yyyy-MM-dd"; String DATETIME = "yyyy-MM-dd HH:mm:ss"; String DATETIME_MM = "yyyy-MM-dd HH:mm"; String DATETIME_SSS = "yyyy-MM-dd HH:mm:ss.SSS"; String TIME = "HH:mm"; String TIME_SS = "HH:mm:ss"; // // 系统时间格式 // ---------------------------------------------------------------------------------------------------- String SYS_DATE = "yyyy/MM/dd"; String SYS_DATETIME = "yyyy/MM/dd HH:mm:ss"; String SYS_DATETIME_MM = "yyyy/MM/dd HH:mm"; String SYS_DATETIME_SSS = "yyyy/MM/dd HH:mm:ss.SSS"; // // 无连接符模式 // ---------------------------------------------------------------------------------------------------- String NONE_DATE = "yyyyMMdd"; String NONE_DATETIME = "yyyyMMddHHmmss"; String NONE_DATETIME_MM = "yyyyMMddHHmm"; String NONE_DATETIME_SSS = "yyyyMMddHHmmssSSS"; }
在
Symbol
接口定义了常用的特殊符号:interface Symbol { String SIGH = "!"; String AT = "@"; String WELL = "#"; String DOLLAR = "$"; String RMB = "¥"; String PERCENTAGE = "%"; String AND = "&"; String STAR = "*"; String MIDDLE_LINE = "-"; String LOWER_LINE = "_"; String EQUAL = "="; String PLUS = "+"; String COLON = ":"; String SEMICOLON = ";"; String COMMA = ","; String POINT = "."; String SLASH = "/"; String DOUBLE_SLASH = "//"; String BACKSLASH = "\\"; String QUESTION = "?"; }
-
AopProxy
:提供self()方法便于获取自身接口代理对象,常用在一个事务方法里调用当前类的其它事务方法,如果不使用代理对象调用方法,本质使用的是原始对象,因而可能导致事务或AOP拦截不生效。
2.2 config
config 包提供了配置工具。
-
Configurer
:程序中自定义的 Properties 类,可实现该接口。在项目启动时,
Configurer
配置器会获取CustomProperties
子类中配置的属性并缓存起来,在程序运行期间,可通过Configurer
提供的静态方法根据编码获取对应的配置值,比较方便。但注意Configurer是运行时获取配置属性,不支持编译时获取属性。 -
Covered
/Extended
:在依赖扩展开发中,我们一般需要自定义
Covered
/Extended
接口,如果完全替换了某个类,需要标识该类为Covered,如果是基于某个类新增了某些功能,需要标识该类为Extended。主要目的在于方便我们知道扩展开发中哪些是继承的,哪些是覆盖的。 一般情况不会使用。
2.3 exception
exception 包提供了基础的异常类,以及全局异常处理器:
BaseExceptionHandler
:异常处理器,拦截各类异常,获取多语言消息,返回 ResponseEntity。CheckedException
:受检异常类,继承自Exception
,程序中需要抛出一定需要捕捉的异常时,可使用该异常类。IllegalOperationException
:非法操作异常,对于某些不能进入的方法、操作,可直接抛出该异常。MessageException
:在程序中,某些消息在抛出时已经处理过,不需要异常处理器再去获取多语言消息,可使用该异常,异常处理器会直接将消息返回。NotLoginException
:未登录异常。OptimisticLockException
:乐观锁检查异常。
2.4 util
util 包提供了一些常用的扩展的工具类:
AssertUtils
:Assert 扩展CheckStrength
:检测密码强度工具FieldNameUtils
: 驼峰-下划线互转EncoderUtils
: 对文件名称进行编码,处理一些特殊字符。EncryptionUtils
:加解密工具类,提供了MD5
、AES
、RSA
、RSA2
等加密方式Reflections
: 反射工具类Regexs
: 正则表达式工具类,提供了常用的正则表达式常量及校验方法Results
:返回 ResponseEntity 对象UUIDUtils
:生成UUIDValidUtils
: 数据校验工具EncryptionUtils
:加密解密工具类,如:MD5 非对称加密、AES 对称加密、RSA 对称加密、RSA2 对称加密Sequence
:分布式高效有序ID生产工具StringPool
:String 相关常量SensitiveUtils
:敏感信息工具类ResponseUtils
:响应处理工具类PinyinUtils
:拼音处理工具类- ….
2.5 redis
- redis 包提供封装好的
RedisHelper
工具类,可以方便地操作各类redis数据结构。 - 同时,提供了线程安全的支持动态切换 redis database 的
DynamicRedisHelper
,DynamicRedisHelper
继承自RedisHelper
,在代码中只需注入RedisHelper
即可。 - 动态切 redis database 的功能默认开启,可配置
hzero.redis.dynamic-database=false
关闭该功能。 - 在需要切换 database 的地方,调用
redisHelper.setCurrentDatabase(int database)
即可,同时必须调用redisHelper.clearCurrentDatabase()
清除当前操作 database,否则当前线程将一直使用这个 database ,对于同一个线程内多次 redis 操作可能会有影响。
2.6 cache
cache下主要提供了一个功能,使用注解根据配置从缓存中获取值。
-
此功能默认不开启,可配置
hzero.cache-value.enable=true
来开启该功能。 -
使用方式,比如,将用户ID和用户名缓存到redis中,大部分情况下我们只有用户ID,此时我们可以根据用户ID来获取用户名。
主要使用到的注解有两个:@CacheValue
和@ProcessCacheValue
。对于某个DTO,有字段用到该功能时,需要实现Cacheable
接口,标识为可从缓存中取值的对象,这样便于对头行结构中的字段进行处理。 -
如下,DTO中有一个 createdBy 字段,我们需要根据该创建人ID获取到创建人姓名,通过
@CacheValue
来从redis中获取值:key
指定缓存的key,支持占位符的形式;primaryKey
指定根据哪个字段匹配;searchKey
指定从redis结构中要查找的字段;structure
指定redis的数据结构。缓存的数据结构不同,CacheValue的配置也不同,具体可参考源码注释详解。
public class DemoDTO implements Cacheable {
private Long createdBy; // 创建人ID
@CacheValue(key = HZeroCacheKey.USER, primaryKey = "createdBy", searchKey = "realName",
structure = CacheValue.DataStructure.MAP_OBJECT)
private String createdUserName; // 创建人姓名
// getter/setter
}
- 配置好后,还需在查询的 service 或 controller 的方法上加上
@ProcessCacheValue
注解,以此进行AOP拦截处理。
2.7 captcha
captcha 下提供了基础的验证码功能封装。
- 如果需要开启验证码功能,首先需要配置
hzero.captcha.enable=true
。 CaptchaProperties
:提供了图片验证码和信息验证码的常用配置,如验证码的长宽,验证码来源、过期时间等。对于信息验证码,可配置发送验证码间隔时间(interval
)、限制时间内发送次数上限(limitTime
)、次数限制在多长时间内(limitInterval
)等等。CaptchaImageHelper
:提供图片验证码功能,调用generateAndWriteCaptchaImage
生成图片验证码,会将验证码缓存到redis中,并将captchaKey
和captcha
写到 cookie 中。调用checkCaptcha
方法检查验证码正确与否,调用getCaptcha
方法从缓存中获取验证码。CaptchaMessageHelper
:用于短信验证码或者邮箱验证码,只用于生成、校验验证码,并不会直接发送验证码,发送验证码可使用hzero-boot-message
客户端。该helper主要封装了生成验证码、校验验证码时的各种验证,并返回相应的多语言消息,验证码及各种key、消息都封装到CaptchaResult
返回,需要自行处理结果。
2.8 message
message 包提供国际化消息相关的操作。
HZeroCoreMessageSource
:hzero-starter-core
默认的MessageSource
,由于在项目中,自动注入的MessageSource
只能获取到当前 classpath 下的资源文件,无法获取到 jar 包内的资源文件,因此建议每个独立的 jar 包都开发一个独有的 MessageSource 来获取当前 jar 下的资源文件。MessageAccessor
:获取当前 classpath 下资源多语言的工具,封装 Spring 的MessageSourceAccessor
,提供多种便捷的方法。
2.9 algorithm
常用算法工具。
tree(递归构建树)
-
功能说明:将具有层级结构的数据使用递归关联起来,父对象中会有一个children列表对象来存放子子对象。
-
使用方式
- Bean对象继承
org.hzero.core.algorithm.tree.Child
类,泛型为子对象的类型,也就是当前Bean的类 - 调用
org.hzero.core.algorithm.tree.TreeBuilder.buildTree(...)
静态方法构建树List<T> objList
: 该参数为原数据列表Node<P, T> nodeOperation
: 该参数为接口,继承了Key和ParentKey接口,需要自行实现,包含两个方法,getKey()方法用户获取当前节点的Key,getParentKey()用于获取父节点的Key,当前节点的key等于子节点的parentKey()时建立关联关系P rootKey
: 该参数为根节点的key,这个参数非必须,但请尽可能提供这个参数,如果不提供,会多遍历一次列表取构建根节点Key<P, T> key
: 获取当前节点的keyParentKey<P, T> parentKey
: 获取父节点的Key
- Bean对象继承
-
使用示例
class Entity extentds org.hzero.core.algorithm.tree.Child<Entity> {
Integer id;
Integer parentId;
// other field ...
// getter and setter ...
}
// method
List<Entity> objList = // from anywhere...
List<Entity> result = org.hzero.core.algorithm.tree.TreeBuilder.buildTree(objList, null, Entity::getId, Entity::getParentId)
[ [
{ {
"id":1, "id":1,
"parentId":null, "parentId":null,
... "children":[{
},{ "id":2,
"id":2, "parentId":1,
"parentId":1, -> ...
... },{
},{ "id":3,
"id":3, "parentId":1,
"parentId":1, ...
... }]
} ...
... }
] ]
structure(自定义数据结构)
- 功能说明:提供一些自定义的数据结构
- 使用说明
org.hzero.core.algorithm.structure.LinkedQueue
: 有序队列,基于LinkedList实现,线程不安全,每次add/append元素之后的数据都是按照顺序排列的,每次插入时使用二分法查找插入的位置。
2.10 jackson
封装了一些jackson序列化和反序列化的操作,支持Java8时间格式的序列化,使用前需要在Spring Boot启动类上添加org.hzero.core.jackson.annotation.EnableObjectMapper
注解。
忽略时区转换
- 功能说明:默认情况下,所有
java.util.Date
在序列化和反序列化时会按照当前用户设置的时区对时间进行转换(固定格式yyyy-MM-dd HH:mm:ss
),如果时间不需要做转换,可以使用该功能忽略时区转换。 - 使用说明
- 序列化和反序列化时忽略时区转换:在字段上添加
@org.hzero.core.jackson.annotation.IgnoreTimeZone
注解 - 序列化时忽略时区转换:在字段上添加
@com.fasterxml.jackson.databind.annotation.JsonSerialize(using = org.hzero.core.jackson.serializer.IgnoreTimeZoneDateSerializer)
注解 - 反序列化时忽略时区转换:在字段上添加
@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = org.hzero.core.jackson.serializer.IgnoreTimeZoneDateDeserializer)
注解
- 序列化和反序列化时忽略时区转换:在字段上添加
字符串两端空格过滤
- 功能说明:前端往后端传输数据时,有些字段需要过滤两端空格,例如编码等,添加注解可以在反序列化时过滤掉空格。
- 使用说明:在字段上添加注解
@org.hzero.core.jackson.annotation.Trim
注解,可以指定不同的过滤策略,默认两端过滤,也可以设置左或者右一端。
敏感信息加密
- 功能说明:后端往前端传输数据时,有些数据可能需要按照某种规则屏蔽掉敏感信息,例如电话号码中间四位显示“*”。
- 使用说明
- **在数据返回前端之前,调用
org.hzero.core.jackson.sensitive.SensitiveHelper.open()
**方法,开启敏感信息屏蔽,当前线程内有效,一次序列化之后自动关闭。 - 在返回Bean的字段上添加
@org.hzero.core.jackson.annotation.Sensitive
注解,注解中可以指定多种规则取屏蔽敏感信息。left
: 从左边开始前 n 位替换right
: 从右边开始后 n 位替换cipher
: 复杂密文规则,下标从1开始,屏蔽某一位字符直接指定下标即可;屏蔽某一个范围可用下标1-下标2
,或者下标1-
表示屏蔽某一位及之后所有;多个规则之间可以用,
分割,或者用数组形式传递。例如:4-7,9,11-
表示第4,5,6,7,9,11以及11之后的位使用加密字符替换clear
: 明文规则,使用方式痛cipher
,结果相反symbol
: 加密字符,默认*
reverse
: 规则反转,指定cipher/clear
时无效。
- **在数据返回前端之前,调用
2.11 convert
封装了一些自定义的参数转换,可以通过hzero.date.converter.enable
配置关闭或者开启这些转换器,默认开启。
Date
- 功能说明 : 按照用户设置的时区对时间做反序列化,固定格式
yyyy-MM-dd HH:mm:ss
- 使用说明 : 需要使用
java.util.Date
LocalDate
- 功能说明 : Java8日期类型,仅包含年月日,固定格式
yyyy-MM-dd
- 使用说明 : 需要使用
java.time.LocalDate
三、版本更新日志
0.8.0.RELEASE [2019-3-29]
- 删除无用代码文件:
EntityFactory
、ApplicationContextEntityFactory
、HeaderParamFilter
- 增加
MessageAccessor
获取资源文件消息存取器。 - 将
starter-common
包下的jackson
、convert
、SensitiveUtils
、TrimUtils
移到starter-core
下。 - 修复已知的bug