java自定义注解实现数据脱敏

前言:

实现log脱敏 也可以实现注解脱敏!

1.注解

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;

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-11-10 09:00
 * @Version 1.0
 **/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
public @interface DataMasking {

    /**
     * 数据脱敏类型
     */
    DataMaskingType type() default DataMaskingType.CUSTOM;

    /**
     * 脱敏开始位置(包含)
     */
    int start() default 0;

    /**
     * 脱敏结束位置(不包含)
     */
    int end() default 0;

}

2.log脱敏循环coutroller调DataMaskFor  注解脱敏coutroller调DataMask方法

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.DesensitizedUtil;
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 org.apache.commons.lang.ArrayUtils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Objects;

/**
 * @program: sxsoft_expert
 * @ClassName DataMaskingSerialize
 * @description: 自定义序列化类
 * @author: 小帅哥
 * @create: 2023-11-10 09:00
 * @Version 1.0
 **/

public class DataMaskingSerialize  implements ContextualSerializer {

    private static Integer start;

    private static Integer end;


    public static TestEntity DataMaskFor(TestEntity entity){
        TestEntity obj = TestEntity.builder()
                .userId(entity.getUserId())
                .userName(entity.getUserName())
                .password(entity.getPassword())
                .address(entity.getAddress())
                .email(entity.getEmail())
                .fixedPhone(entity.getFixedPhone())
                .mobilePhone(entity.getMobilePhone())
                .carLicense(entity.getCarLicense())
                .bankCard(entity.getBankCard())
                .idCard(entity.getIdCard())
                .custom(entity.getCustom())
                .noMask(entity.getNoMask())
                .build();
        Field[] declaredFields = obj.getClass().getDeclaredFields();



        Arrays.asList(declaredFields).stream().forEach(fielfd -> {

            if(!ArrayUtils.isEmpty(fielfd.getAnnotations())){
//                fielfd.set(obj, o);


                DataMasking annotation = (DataMasking)fielfd.getAnnotations()[0];
                DataMaskingType type = annotation.type();

                try {
                    if(!fielfd.isAccessible()){
                        fielfd.setAccessible(true);
                    }

                    Object o = DataMask(fielfd.get(obj), type);
                    Class<?> type1 = fielfd.getType();

                    if(type1.isAssignableFrom(Integer.class)){
                        fielfd.set(obj, Integer.valueOf(o.toString()));
                    }
                    else if(type1.isAssignableFrom(String.class) && Objects.nonNull(o)){
                        fielfd.set(obj, o.toString());
                    }else{
                        fielfd.set(obj, o);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        });
        return obj;
    }

    public static Object DataMask(Object o ,DataMaskingType type) throws IOException {
        Object obj = null;
        String value = String.valueOf(o);
        switch (type) {
            //userId
            case USER_ID:
                obj = String.valueOf(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.USER_ID));
                break;
            //中文名
            case CHINESE_NAME:
                obj = (DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.CHINESE_NAME));
                break;
            //身份证号
            case ID_CARD:
                obj = (DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.ID_CARD));
                break;
            //座机
            case FIXED_PHONE:
                obj = (DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.FIXED_PHONE));
                break;
            //手机号
            case MOBILE_PHONE:
                obj = (DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.MOBILE_PHONE));
                break;
            //地址
            case ADDRESS:
                obj = (DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.ADDRESS));
                break;
            //邮箱
            case EMAIL:
                obj = (DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.EMAIL));
                break;
            case BANK_CARD:
                obj = (DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.BANK_CARD));
                break;
            //密码
            case PASSWORD:
                obj = (DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.PASSWORD));
                break;
            //中国大陆车牌号
            case CAR_LICENSE:
                obj = (DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.CAR_LICENSE));
                break;
//            case IPV4:
//                obj = (DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.IPV4));
//                break;
//            case IPV6:
//                obj = (DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.IPV6));
//                break;
            //自定义
            case CUSTOM:
                obj = CharSequenceUtil.hide(value, 3,5);
                break;
            default:
                break;
        }
        return obj;
    }

    @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());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }
}

3.枚举 脱敏类型

/**
 * @program: sxsoft_expert
 * @ClassName DataMaskingType
 * @description:脱敏枚举
 * @author: 小帅哥
 * @create: 2023-11-10 09:00
 * @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;
}

4.类

import lombok.*;
/**
 * @program: sxsoft_expert
 * @ClassName TestEntity
 * @description:
 * @author: 小帅哥
 * @create: 2023-11-10 09: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.coutroller(log脱敏循环coutroller调DataMaskFor  注解脱敏coutroller调DataMask方法)

import com.example.demo11.service.impl.TestServiceImpl;
import com.example.demo11.uilt.TestEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Coutroller {

    @Autowired
    private TestServiceImpl testService;
    @RequestMapping(value="/test")
    public TestEntity test()  {

        //只能直接返回实体?
        TestEntity entity ;
        entity = testService.tt();
        return entity;

    }

}

完全可以实现log脱敏!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值