使用注解形式实现脱敏

引子

    最近老大想作一个日志脱敏的需求,看了网上的一些方案都不太满意,可是仍是借鉴了一些网上的代码实现了该功能java

实现原理

    实现原理很简单就是重写了 fastjson ValueFilter.class process方法git

使用方法

    在实体上标明须要脱敏的字段json

    打印日志时使用自定义公共脱敏方法 输出日志测试

    举例    spa

        1:@SensitiveAnn(type = SensitiveTypeEnum.PHONE)    .net

        2:SensitiveInfoUtils.toJsonString(cardInfo)日志

源码

    https://gitee.com/shiliang_feng/codes/iqlnwjsezh53umbpag8vx88code

实现

       定义一个@interface Ann   里面有一个自定义枚举的属性blog

    

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.demo.enums.SensitiveTypeEnum;

/**
 * 
 * @ClassName: SensitiveAnn
 * @Description:脱敏字段注解 
 * @author shiliang.feng
 * @date 2019年8月16日 下午5:11:20
 *
 */
@Target({ ElementType.TYPE, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveAnn {
	SensitiveTypeEnum type();
}

       枚举的代码以下ip

    

public enum SensitiveTypeEnum {
	/** 身份证号码 */
	ID_CARD,
	/** 银行卡号 */
	BANK_CARD,
	/** 手机号码 */
	PHONE,
	/** 名字 */
	NAME,
	/** 邮箱 */
	EMAIL

}

实现具体脱敏方法

    

/**
	 * 
	 * @Title: mobilePhone
	 * @Description: [手机号码] 前三位,后两位,其余隐藏<例子:138********34>
	 * @author 1100122
	 * @date 2019年3月22日 下午7:56:10
	 * @param num
	 * @return 
	 * @throws
	 */
	public static String mobilePhone(String num) {
		if (StringUtils.isBlank(num)) {
			return "";
		}
		return StringUtils.left(num, 3).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(num, 2), StringUtils.length(num), "*"), "***"));
	}

	/**
	 * 
	 * @Title: idCardNum
	 * @Description:  [身份证号] 显示前六位,最后两位,其余隐藏。共计18位或者15位。<例子:152728*********62>
	 * @author 1100122
	 * @date 2019年3月22日 下午7:56:03
	 * @param num
	 * @return 
	 * @throws
	 */
	public static String idCardNum(String num) {
		if (StringUtils.isBlank(num)) {
			return "";
		}
		return StringUtils.left(num, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(num, 2), StringUtils.length(num), "*"), "******"));
	}

	/**
	 * 
	 * @Title: bankCard
	 * @Description:[银行卡号] 前六位,后四位,其余用星号隐藏每位1个星号<例子:6222600**********1234>
	 * @author 1100122
	 * @date 2019年3月22日 下午7:55:55
	 * @param cardNum
	 * @return 
	 * @throws
	 */
	public static String bankCard(String cardNum) {
		if (StringUtils.isBlank(cardNum)) {
			return "";
		}
		return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "******"));
	}

	/**
	 * 
	 * @Title: desensitizeEmail
	 * @Description:[电子邮箱] 邮箱前缀仅显示第一个字母,前缀其余隐藏,用星号代替,@及后面的地址显示<例子:g**@163.com>
	 * @author 1100122
	 * @date 2019年3月22日 下午7:51:29
	 * @param email
	 * @return 
	 * @throws
	 */
	public static String desensitizeEmail(String email) {
		if (StringUtils.isBlank(email)) {
			return "";
		}
		int index = StringUtils.indexOf(email, "@");
		if (index <= 1) {
			return email;
		} else {
			return StringUtils.rightPad(StringUtils.left(email, 1), index, "*").concat(StringUtils.mid(email, index, StringUtils.length(email)));
		}
	}

	/**
	 * 
	 * @Title: desensitizeName
	 * @Description: [中文姓名] 只显示第一个汉字,其余隐藏为2个星号<例子:李**>
	 * @author 1100122
	 * @date 2019年3月22日 下午7:51:37
	 * @param fullName
	 * @return 
	 * @throws
	 */
	private static final Object desensitizeName(String fullName) {
		if (StringUtils.isBlank(fullName)) {
			return "";
		}
		String name = StringUtils.left(fullName, 1);
		return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
	}

定义一个总入口

    

/**
	 * 
	 * @Title: toJsonString
	 * @Description: 日志输出
	 * @author shiliang.feng
	 * @date 2019年8月16日 下午2:25:10
	 * @param object
	 * @return
	 */
	public static String toJsonString(Object object) {
		return JSON.toJSONString(object, getValueFilter());
	}

重写ValueFilter.process方法

/**
	 * 
	 * @Title: getValueFilter
	 * @Description: 日志脱敏主方法
	 * @author shiliang.feng
	 * @date 2019年8月16日 下午2:25:28
	 * @return
	 */
	private static final ValueFilter getValueFilter() {
		return (Object obj, String key, Object value) -> {
			try {
				SensitiveAnn annotation = obj.getClass().getDeclaredField(key).getAnnotation(SensitiveAnn.class);
				if (null != annotation && value instanceof String) {
					String strVal = (String) value;
					if (StringUtils.isNotBlank(strVal)) {
						switch (annotation.type()) {
						case PHONE:
							return mobilePhone(strVal);
						case ID_CARD:
							return idCardNum(strVal);
						case BANK_CARD:
							return bankCard(strVal);
						case NAME:
							return desensitizeName(strVal);
						case EMAIL:
							return desensitizeEmail(strVal);
						default:
							break;
						}
					}
				}
			} catch (NoSuchFieldException | SecurityException e) {
			}
			return value;
		};
	}

测试一下

public static void main(String[] args) {
		CardInfo cardInfo = new CardInfo();
		cardInfo.setCardId("6228480402564890018");
		cardInfo.setName("冯小明");
		cardInfo.setPhone("18699999999");
		cardInfo.setBank("463553564656545646");
		System.out.println(SensitiveInfoUtils.toJsonString(cardInfo));
		System.out.println(JSON.toJSONString(cardInfo));
	}

结果以下

相关文章
相关标签/搜索