自定義Json註解實現輸出日誌欄位脫敏
阿新 • • 發佈:2019-02-12
背景: 在日誌輸出的時候,有時會輸出一些使用者的敏感資訊,如手機號,身份證號,銀行卡號等,現需要對這些資訊在日誌輸出的時候進行脫敏處理
思路: 使用fastjson的ValueFilter對帶有自定義註解的欄位進行過濾
/**
* 敏感資訊型別
*
* @author worstEzreal
* @version V1.0.0
* @date 2017/7/19
*/
public enum SensitiveType {
ID_CARD,
BANK_CARD,
PHONE
}
/** * 脫敏欄位註解 * * @author worstEzreal * @version V1.0.0 * @date 2017/7/19 */ @Target({ElementType.TYPE, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface SensitiveInfo { SensitiveType type(); }
/** * 日誌敏感資訊脫敏工具 * * @author worstEzreal * @version V1.0.0 * @date 2017/7/19 */ public class SensitiveInfoUtils { public static String toJsonString(Object object) { return JSON.toJSONString(object, getValueFilter()); } private static String desensitizePhoneOrIdCard(String num) { if (StringUtils.isBlank(num)) { return ""; } return StringUtils.left(num, 3).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*"), "***")); } private static String desensitizeBankCard(String cardNum) { if (StringUtils.isBlank(cardNum)) { return ""; } return StringUtils.left(cardNum, 4).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "****")); } private static final ValueFilter getValueFilter() { return new ValueFilter() { @Override public Object process(Object obj, String key, Object value) {//obj-物件 key-欄位名 value-欄位值 try { Field field = obj.getClass().getDeclaredField(key); SensitiveInfo annotation = field.getAnnotation(SensitiveInfo.class); if (null != annotation && value instanceof String) { String strVal = (String) value; if (StringUtils.isNotBlank(strVal)) { switch (annotation.type()) { case PHONE: return desensitizePhoneOrIdCard(strVal); case ID_CARD: return desensitizePhoneOrIdCard(strVal); case BANK_CARD: return desensitizeBankCard(strVal); default: break; } } } } catch (NoSuchFieldException e) { //找不到的field對功能沒有影響,空處理 } return value; } }; } public static void main(String[] args) { CardInfo cardInfo = new CardInfo(); cardInfo.setId("11111111111111111"); cardInfo.setCardId("6228480402564890018"); System.out.println(SensitiveInfoUtils.toJsonString(cardInfo)); } }
附CardInfo類:
public class CardInfo { private String userId; private String name; @SensitiveInfo(type = SensitiveType.ID_CARD) private String certId; @SensitiveInfo(type = SensitiveType.BANK_CARD) private String cardId; private String bank; private String phone; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCertId() { return certId; } public void setCertId(String certId) { this.certId = certId; } public String getCardId() { return cardId; } public void setCardId(String cardId) { this.cardId = cardId; } public String getBank() { return bank; } public void setBank(String bank) { this.bank = bank; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }