java自定义注解实现数据脱敏
1、自定义序列化
package com.sxsoft.admin.entity.customEntity; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.util.DesensitizedUtil; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.BeanProperty; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.ContextualSerializer; import com.sxsoft.admin.Component.DataMasking; import com.sxsoft.admin.enums.DataMaskingType; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import java.io.IOException; import java.util.Objects; /** * @program: sxsoft_expert * @ClassName DataMaskingSerialize * @description: 自定义序列化类 * @author: 黄涛 * @create: 2023-10-25 07:56 * @Version 1.0 **/ @AllArgsConstructor @NoArgsConstructor public class DataMaskingSerialize extends JsonSerializer implements ContextualSerializer { private DataMaskingType type; private Integer start; private Integer end; @Override public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { String value = (String) o; switch (type) { //userId case USER_ID: jsonGenerator.writeString(String.valueOf(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.USER_ID))); break; //中文名 case CHINESE_NAME: jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.CHINESE_NAME)); break; //身份证号 case ID_CARD: jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.ID_CARD)); break; //座机 case FIXED_PHONE: jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.FIXED_PHONE)); break; //手机号 case MOBILE_PHONE: jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.MOBILE_PHONE)); break; //地址 case ADDRESS: jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.ADDRESS)); break; //邮箱 case EMAIL: jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.EMAIL)); break; case BANK_CARD: jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.BANK_CARD)); break; //密码 case PASSWORD: jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.PASSWORD)); break; //中国大陆车牌号 case CAR_LICENSE: jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.CAR_LICENSE)); break; // case IPV4: // jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.IPV4)); // break; // case IPV6: // jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.IPV6)); // break; //自定义 case CUSTOM: jsonGenerator.writeString(CharSequenceUtil.hide(value, start, end)); break; default: break; } } @Override public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException { if (Objects.nonNull(beanProperty)) { //判断是否为string类型 if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) { DataMasking anno = beanProperty.getAnnotation(DataMasking.class); if (Objects.isNull(anno)) { anno = beanProperty.getContextAnnotation(DataMasking.class); } if (Objects.nonNull(anno)) { return new DataMaskingSerialize(anno.type(), anno.start(), anno.end()); } } return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty); } return serializerProvider.findNullValueSerializer(null); } }
2、自定义枚举
package com.sxsoft.admin.enums; /** * @program: sxsoft_expert * @ClassName DataMaskingType * @description:脱敏枚举 * @author: 黄涛 * @create: 2023-10-25 07:54 * @Version 1.0 **/ public enum DataMaskingType { /** * 用户ID */ USER_ID, /** * 中文名 */ CHINESE_NAME, /** * 身份证号 */ ID_CARD, /** * 座机 */ FIXED_PHONE, /** * 手机号 */ MOBILE_PHONE, /** * 地址 */ ADDRESS, /** * 邮箱 */ EMAIL, /** * 密码 */ PASSWORD, /** * 中国大陆车牌号 */ CAR_LICENSE, /** * 银行卡号 */ BANK_CARD, /** * IPv4地址 */ IPV4, /** * IPv6地址 */ IPV6, /** * 自定义类型 */ CUSTOM; }
3、自定义注解
package com.sxsoft.admin.Component; import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.sxsoft.admin.entity.customEntity.DataMaskingSerialize; import com.sxsoft.admin.enums.DataMaskingType; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @program: sxsoft_expert * @ClassName DataMasking * @description: 数据脱敏自定义注解 * @author: 黄涛 * @create: 2023-10-25 07:55 * @Version 1.0 **/ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonSerialize(using = DataMaskingSerialize.class) public @interface DataMasking { /** * 数据脱敏类型 */ DataMaskingType type() default DataMaskingType.CUSTOM; /** * 脱敏开始位置(包含) */ int start() default 0; /** * 脱敏结束位置(不包含) */ int end() default 0; }
4、测试实体
package com.sxsoft.admin.entity.customEntity; import com.sxsoft.admin.Component.DataMasking; import com.sxsoft.admin.enums.DataMaskingType; import lombok.*; /** * @program: sxsoft_expert * @ClassName TestEntity * @description: * @author: 黄涛 * @create: 2023-10-25 08:00 * @Version 1.0 **/ @Data @Builder @ToString @AllArgsConstructor @NoArgsConstructor public class TestEntity { @DataMasking(type = DataMaskingType.USER_ID) private Integer userId; @DataMasking(type = DataMaskingType.CHINESE_NAME) private String userName; @DataMasking(type = DataMaskingType.ADDRESS) private String address; @DataMasking(type = DataMaskingType.ID_CARD) private String idCard; @DataMasking(type = DataMaskingType.FIXED_PHONE) private String fixedPhone; @DataMasking(type = DataMaskingType.MOBILE_PHONE) private String mobilePhone; @DataMasking(type = DataMaskingType.EMAIL) private String email; @DataMasking(type = DataMaskingType.PASSWORD) private String password; @DataMasking(type = DataMaskingType.CAR_LICENSE) private String carLicense; @DataMasking(type = DataMaskingType.BANK_CARD) private String bankCard; // @DataMasking(type = DataMaskingType.IPV4) // private String ipv4; // // @DataMasking(type = DataMaskingType.IPV6) // private String ipv6; @DataMasking(type = DataMaskingType.CUSTOM,start = 3,end = 9) private String custom; /** * 不进行数据脱敏的字段 */ private String noMask; }
5、使用
@RequestMapping(value="/test") public TestEntity test() { //只能直接返回实体? TestEntity entity = TestEntity.builder() .userId(1234567890) .userName("张三") .password("12") .address("河南省郑州市中原区") .email("xxxx@xx.com") .fixedPhone("0838-5553792") .mobilePhone("13888888888") .carLicense("豫P3U253") .bankCard("1679374639283740") .idCard("412711223344556677") .custom("289073458794") .noMask("我是不需要数据脱敏的字段") .build(); return entity; }
问题:好像只有直接返回实体才能脱敏,如果要对返回结果封装要怎么处理??
吾乃代码搬运工,侵联删
分类:
Java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了