# dictionary-solon-plugin
**Repository Path**: uidoer/dictionary-solon-plugin
## Basic Information
- **Project Name**: dictionary-solon-plugin
- **Description**: java 字典翻译 + 字段替换 + 字段脱敏
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: http://dictionary.rish.top
- **GVP Project**: No
## Statistics
- **Stars**: 20
- **Forks**: 2
- **Created**: 2024-11-01
- **Last Updated**: 2025-09-27
## Categories & Tags
**Categories**: Uncategorized
**Tags**: SpringBoot, solon, 字典翻译, 字典转换, 数据脱敏
## README
###### 直接上例子
```java
// 1. 实体 必须实现 DictEntity
public class UserMember implements DictEntity {
// 2. 固定map,用key,转换为value
@KvConverter({
@Kv(k="1",v="男"),
@Kv(k="0",v="女"),
})
public int sex;
// 3. 用枚举值,转换为枚举名称
@EnumConverter(EnumSmall.class)
public int tx;
// 4. 邮箱脱敏
@DesensitizedConverter(EmailDesensitizedAction.class)
public String email = "2225w@qq.com";
// 5. 手机号码脱敏
@DesensitizedConverter(PhoneDesensitizedAction.class)
public String phone = "1357759998";
// 6. 支持1v1对象嵌套,支持map、colloct、array对象嵌套
UserMember member;
}
```
###### 返回的json
```json
{
"tx":0,
"txName":"FF_23",
"sex":0,
"sexName":"女",
"phone":"135****9998",
"email":"2****@qq.com",
"member": {
"tx":0,
"txName":"FF_23",
"sex":0,
"sexName":"女",
"phone":"135****9998",
"email":"2****@qq.com"
}
}
```
###### 自定义注解,只需3步
```xml
top.rish.converter
dictionary-solon-plugin
1.0.1
top.rish.converter
dictionary-spring-boot-starter
1.0.1
```
```java
// 1. 定义注解 EnumConverter
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface EnumConverter {
// 例如,你想将规则定为:用枚举的value替换为枚举的名称
Class extends Enum>> value();
}
// 2. 实现EnumConverter的handler.
// 如果你不想做下面的第3步,你可以用 @Component 直接托管到solon 、springboot的容器中
public class EnumConverterHandlerDict implements DictConvertHandler {
@Override
public void convert(MetaMap metaMap /* 当前继承了DictEntity对应的一个map【中间产物】 */,
DictEntity entity /*当前对象的值*/,
Object value /*当前字段的值*/,
FieldWrap fieldWrap /*当前字段的元信息*/,
EnumConverter convert /*你的注解,传入的值*/ ) {
// 这里进行转换为你想要的内容,
// 对metaMap.put()一下,
// 该jsonObject就会有你新put的字段了
Class extends Enum>> enumClass = convert.value();
Enum> ev = RefKit.getEnumByValue(enumClass, value);
if(ObjKit.isNotEmpty(ev)){
// 这里是动态创建 应变量字段 x +"Name" 字段。如:原字段是x,那么对象中多创建一个字段xName.
// 1. 首先我们要明白:x是亘古不变的且用于代码判断和运算的。而xName是为了提高x的业务可读和便于适应业务语境。
// 所以xName是个回显值。那么xName不能参与重要业务的代码判断和运算【这个很重要】。
// 2.要不然会出现回显值被覆盖的情况:
// 例如:DictEntity早已就字段xName的值是‘小红’,那么这里覆盖DictEntity字段xName的值为其他,xName的值保不准就变成‘小龙’了
// 所以,使用了 DictConvertHandler + @DictEntity 后,不需要手动创建回显字段xName;
// 3. 你只需要按第1点规范实体类中的字段设计。
metaMap.set(fieldWrap.getName()+"Name", Objects.toString(ev));
}
}
}
// 3. 集中地注册bean到solon容器
@Configuration
public class DictionaryConfiguration {
@Bean
public KvConverterHandlerDict kvConverterHandler() {
return new KvConverterHandlerDict();
}
@Bean
public DesensitizedConverterHandlerDict desensitizedConverterHandler() {
return new DesensitizedConverterHandlerDict();
}
@Bean
public EnumConverterHandlerDict enumConverterHandler() {
return new EnumConverterHandlerDict();
}
}
```
###### 工作原理和内存缓存:
1. 调用 SolonDictConvertFactory::registerHandler方法,
1.1: DictConvertHandler接口的子类[处理类] (必须实现convert方法),会缓存到 SolonDictConvertFactory::HANDLERS(List)静态字段【只会存类型,不会存对象】。
1.2: DictConvertHandler extends Annotation> 子类的泛型参数是个[字段注解]。
[字段注解]和[处理类],会缓存到:SolonDictConvertFactory::ANNO_AND_HANDLER(Map)静态字段【只会存类型,不会存对象】。
注意:
1.3 HANDLERS为空,则不进行第2步,所以必须先执行SolonDictConvertFactory::registerHandler方法。
1.4 [字段注解]和[处理类]是一对一关系: 一个DictConvertHandler接口的子类处理类,对应一个字段处理注解[字段注解]
2. 调用 SolonDictConvertFactory::registerDictEntityFields方法,
会将DictEntity子类带有[字段注解]类型的[字典注解字段]类型,缓存到 SolonDictConvertFactory::FIELD_AND_HANDLER(Map)【只会存类型,不会存对象】
3. 传入Object类型的[被解析参数]调用 SolonDictConvertFactory::convert 方法,会递归解析[被解析参数]的对象树的每一个[需转换字段],
按1和2中的[字段注解]和[处理类],逐一调用具体[处理类]的convert方法,转换[需转换字段]。
转换[需转换字段]的过程会产生一个[被解析参数]对应的MetaMap,让用户随心所欲put入新的或覆盖:字段和字段值
注意:递归解析过程中,若报错。那么会直接影响业务的正确运行。
###### 如需要手动解析请参考
到dictionary-solon-plugin-core模块的单元测试(src/test/java)中,
查看[top.rish.converter.solon.test.snack3.Obj2jsonTest::testConverter](https://gitee.com/uidoer/dictionary-solon-plugin/blob/main/dictionary-solon-plugin-core/src/test/java/top/rish/converter/solon/test/snack3/Obj2jsonTest.java) 方法的例子。
###### 实现[处理类]的convert方法,记得认真做好单元测试。
更复杂的业务场景(如:依赖数据库、外部服务的动态字典)需要自己扩展实现.
目前dictionary-solon-plugin-core中提供了4种[处理类],仅仅作为抛砖引玉。
EnumConverterHandlerDict:采用注解的value转enum的name转换
DesensitizedConverterHandlerDict:采用注解声明式的字符级别的正则转换
KvConverterHandlerDict:采用注解声明式的内存级别kv转换