Java日志脱敏工具类(支持自定义逻辑)
背景
在开发过程中,很容易将用户敏感信息,例如手机号码、身份证等,打印在日志平台。为了保护用户数据,又不影响日志的打印,需要将日志中的敏感信息进行脱敏。

效果

强烈建议 pull项目,执行一下项目中
SensitiveUtils#main方法。
特性
- 支持多层级【JSON】/【对象】字段脱敏
- 支持一次多字段脱敏
- 支持自定义脱敏逻辑
- 支持一次脱敏多种数据类型,例如:一个字符串同时脱敏手机号、身份证号
- 连续数组层级脱敏
- 减少侵入业务代码(例如使用注解进行脱敏)
使用
1. 输入为字符串/对象及单JSON路径
// 传入对象
User user = new User();
user.setName("handsometaoa");
user.setPhone("13455556666");
List<SensitivePath> sensitivePaths = Collections.singletonList(SensitivePath.withBuiltInRule("phone", DesensitizedType.MOBILE_PHONE));
String result1 = SensitiveUtils.des(user, new HashSet<>(sensitivePaths));
System.out.println(result1); // {"phone":"134****6666","name":"handsometaoa"}
// 传入JSON字符串
String param2 = "{\"name\":\"handsometaoa\",\"phone\":\"13455556666\"}";
List<SensitivePath> sensitivePaths2 = Collections.singletonList(SensitivePath.withBuiltInRule("phone", DesensitizedType.MOBILE_PHONE));
String result2 = SensitiveUtils.des(param2, new HashSet<>(sensitivePaths2));
System.out.println(result2); // {"phone":"134****6666","name":"handsometaoa"}
2. 输入为字符串/对象及多JSON路径
[
{
"name": "handsometaoa",
"phone": "13444445555",
"parent": [
{
"name": "handsometaoa",
"phone": "13444445555"
}
]
},
{
"name": "handsometaoa",
"phone": "13444445555",
"parent": [
{
"name": "handsometaoa",
"phone": "13444445555",
"parent": [
{
"name": "handsometaoa",
"phone": "13444445555"
}
]
}
]
}
]
上图中,如果要脱敏全部手机号,路径则为 :phone , parent#phone , parent#parent#phone
String param3 = "[{\"name\":\"handsometaoa\",\"phone\":\"13444445555\",\"parent\":[{\"name\":\"handsometaoa\",\"phone\":\"13444445555\"}]}" +
",{\"name\":\"handsometaoa\",\"phone\":\"13444445555\",\"parent\":[{\"name\":\"handsometaoa\",\"phone\":\"13444445555\",\"parent\"" +
":[{\"name\":\"handsometaoa\",\"phone\":\"13444445555\"}]}]}]";
Set<SensitivePath> sensitivePaths3 = SensitivePath.withBuiltInRuleSet(Arrays.asList("phone","parent#phone","parent#parent#phone")
, DesensitizedType.MOBILE_PHONE);
String result3 = SensitiveUtils.des(param3, sensitivePaths3);
System.out.println(result3);
结果展示:
[
{
"parent": [
{
"phone": "134****5555",
"name": "handsometaoa"
}
],
"phone": "134****5555",
"name": "handsometaoa"
},
{
"parent": [
{
"parent": [
{
"phone": "134****5555",
"name": "handsometaoa"
}
],
"phone": "134****5555",
"name": "handsometaoa"
}
],
"phone": "134****5555",
"name": "handsometaoa"
}
]
3. 连续数组JSON脱敏
[
[
{
"parent": [
{
"phone": "15555555555"
},
{
"phone": "15555555555"
}
]
},
{
"parent": [
[
[
{
"phone": "15555555555"
},
{
"phone": "15555555555"
}
]
]
]
}
],
[
{
"parent": [
{
"phone": "15555555555"
}
]
}
]
]
分析可知,上图中,如果要脱敏全部手机号,路径则为 :parent#phone
String param4 = "[[{\"parent\":[{\"phone\":\"15555555555\"},{\"phone\":\"15555555555\"}]},{\"parent\":[[[{\"phone\":\"15555555555\"}" +
",{\"phone\":\"15555555555\"}]]]}],[{\"parent\":[{\"phone\":\"15555555555\"}]}]]";
Set<SensitivePath> sensitivePaths4 = SensitivePath.withBuiltInRuleSet(Collections.singletonList("parent#phone")
, DesensitizedType.MOBILE_PHONE);
String result4 = SensitiveUtils.des(param4, sensitivePaths4);
System.out.println(result4);
结果展示:
[
[
{
"parent": [
{
"phone": "155****5555"
},
{
"phone": "155****5555"
}
]
},
{
"parent": [
[
[
{
"phone": "155****5555"
},
{
"phone": "155****5555"
}
]
]
]
}
],
[
{
"parent": [
{
"phone": "155****5555"
}
]
}
]
]
4. 同时脱敏手机号与密码
{
"name": "handsometaoa",
"password": "123123123",
"phone": "13444445555"
}
分析可知,上图中,如果要脱敏手机号和密码
String param5 = "{\"name\":\"handsometaoa\",\"password\":\"123123123\",\"phone\":\"13444445555\"}";
SensitivePath sensitivePaths51 = SensitivePath.withBuiltInRule("password", DesensitizedType.PASSWORD);
SensitivePath sensitivePaths52 = SensitivePath.withBuiltInRule("phone", DesensitizedType.MOBILE_PHONE);
HashSet<SensitivePath> sensitivePaths5 = new HashSet<>(Arrays.asList(sensitivePaths51,sensitivePaths52));
String result5 = SensitiveUtils.des(param5, sensitivePaths5);
System.out.println(result5);
结果展示:
{
"password": "*********",
"phone": "134****5555",
"name": "handsometaoa"
}
5. 支持自定义脱敏逻辑
{
"name": "张一二"
}
如果想要脱敏上面代码中名字,只留姓名,则可以自定义脱敏逻辑
String param6 = "{\"name\":\"张一二\"}";
SensitivePath sensitivePath = SensitivePath.withCustomRule("name", value -> {
if (ToolUtils.isEmpty( value)){
return "";
}
return MaskUtils.replaceWithAsterisk(value, 1, value.length());
});
String result6 = SensitiveUtils.des(param6, Collections.singleton(sensitivePath));
System.out.println(result6);
结果展示:
{
"name": "张**"
}
已知缺陷
- 暂不支持对String以外类型脱敏
- 暂不支持字符串中【对象JSON字符串】脱敏
{ "info": "{\"data\":\"{\\\"phone\\\":\\\"13444444444\\\"}\"}" }
未来优化方向
增加更多脱敏类型(如身份证号码)已支持 2025-12-04支持一个对象/JSON字符串多种脱敏类型,例如:一个字符串同时脱敏手机号、身份证号已支持 2025-12-04连续数组脱敏(待定)已支持 2025-12-04- 支持非String类型字段脱敏(待定)
- 字符串中【对象JSON字符串】脱敏(待定)
Github地址
本文来自博客园,作者:帅气的涛啊,转载请注明原文链接:https://www.cnblogs.com/handsometaoa/p/18578888

浙公网安备 33010602011771号