# 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> 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> 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 子类的泛型参数是个[字段注解]。 [字段注解]和[处理类],会缓存到: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转换