组件编码
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