在开发中会遇到数据的展示需要做脱敏处理,两种方式:1. 让前端做脱敏处理,但是接口实际上返回了真实数据,所以该方案可行度比较低。2. 后端在序列化的时候做处理,这样既不会影响接口的逻辑,也避免了真实数据在网络中传输。
已更新:脱敏工具类的开发简洁使用,扩展性强,http://t.csdn.cn/S0rKs
后端实现步骤:
- 自定义脱敏器实现JsonSerializer< T >,可以是任意类型的泛型
- 在需要脱敏的属性上添加注解: @JsonSerialize(using = IDCardDesensitization.class)
使用示例:
@JsonSerialize(using = IDCardDesensitization.class)
@ApiModelProperty(value = "身份证号")
private String idCard;
- 手机号脱敏实例:
/**
* @author:
* @Description: 手机号脱敏器
* @Date:
*/
public class PhoneDesensitization extends JsonSerializer<String> {
/**
* 手机号正则
*/
private static final Pattern DEFAULT_PATTERN = Pattern.compile("(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}");
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
try {
gen.writeObject(desensitize(value));
} catch (Exception e) {
gen.writeObject(value);
}
}
/**
* 手机号脱敏 只保留前3位和后4位
*
* @param target 目标数据
* @return
*/
private String desensitize(String target) {
Matcher matcher = DEFAULT_PATTERN.matcher(target);
if (matcher.find()) {
String group = matcher.group();
// 这里的工具使用的是cn.hutool.core.util.StrUtil
// 如果项目中没有使用该包,可以先使用string的substring获取出中间部分的子字符串
// 然后通过replace方法替换 '*' 即可
target = StrUtil.hide(group, 3, 7);
}
return target;
}
}
- 身份证脱敏实例:
/**
* @author:
* @Description: 身份证脱敏器
* @Date:
*/
public class IDCardDesensitization extends JsonSerializer<String> {
/**
* 15位身份证号正则
*/
private static final Pattern PATTERN15 = Pattern.compile("^([1-9][0-9]{5}[0-9]{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)[0-9]{3})$");
/**
* 18位身份证号正则
*/
private static final Pattern PATTERN18 = Pattern.compile("^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$");
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
try {
gen.writeObject(desensitize(value));
} catch (Exception e) {
gen.writeObject(value);
}
}
/**
* 身份证脱敏(18位和15位)
* 先做18位的脱敏处理,如果满足则不会进入15位
* 如果15位身份证不会匹配18位,则进入15位的处理
*
* @param target 目标数据
* @return
*/
public String desensitize(String target) {
target = desensitize(PATTERN18, target);
return desensitize(PATTERN15, target);
}
/**
* 前三位和年份后两位
*
* @param pattern 匹配正则
*/
private String desensitize(Pattern pattern, String target) {
if (StrUtil.isNotBlank(target)) {
Matcher matcher = pattern.matcher(target);
if (matcher.find()) {
int year = pattern.equals(PATTERN18) ? 8 : 6;
String group = matcher.group();
target = StrUtil.hide(group, 0, 2);
target = StrUtil.hide(target, year, year + 2);
}
}
return target;
}
}