项目中打印到控台的敏感信息,需要做脱敏出来
记录下来,防止遗忘
一、重写MessageConverter
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import ch.qos.logback.classic.pattern.MessageConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import com.xxx.xxx.util.utils.SensitiveInfoUtils;
public class SensitiveDataConverter extends MessageConverter {
/**
* 日志脱敏开关
*/
private static String converterCanRun = "true";
/**
* 日志脱敏关键字
*/
// 身份证号码脱敏
private static String[] idNoKeys = new String[] {
"idNo", "contactIdNo", "accountIdNo"
};
// 中文名
private static String[] nameKeys = new String[] {
// "name"
};
// 银行卡号码脱敏
private static String[] bankCardKeys = new String[] {
"bankActId", "cardNo", "cardNum"
};
// 手机号码脱敏
private static String[] mobileKeys = new String[] {
"mobile", "contactTelno"
};
@Override
public String convert(ILoggingEvent event) {
// 获取原始日志
String oriLogMsg = event.getFormattedMessage();
// 获取脱敏后的日志
String afterLogMsg = invokeMsg(oriLogMsg);
return afterLogMsg;
}
/**
* 处理日志字符串,返回脱敏后的字符串
*
* @param msg
* @return
*/
public String invokeMsg(final String oriMsg) {
String tempMsg = oriMsg;
if ("true".equals(converterCanRun)) {
String[] keysArray = this.concatAll(idNoKeys, nameKeys, bankCardKeys, mobileKeys);
for (String key : keysArray) {
int index = -1;
do {
index = tempMsg.indexOf(key, index + 1);
if (index != -1) {
// 判断key是否为单词字符
if (isWordChar(tempMsg, key, index)) {
continue;
}
// 寻找值的开始位置
int valueStart = getValueStartIndex(tempMsg, index + key.length());
// 查找值的结束位置(逗号,分号)
int valueEnd = getValuEndEIndex(tempMsg, valueStart);
// 对获取的值进行脱敏
String subStr = tempMsg.substring(valueStart, valueEnd);
subStr = tuomin(subStr, key);
tempMsg = tempMsg.substring(0, valueStart) + subStr + tempMsg.substring(valueEnd);
}
} while (index != -1);
}
}
return tempMsg;
}
private <T> T[] concatAll(T[] first, T[]... rest) {
int totalLength = first.length;
for (T[] array : rest) {
totalLength += array.length;
}
T[] result = Arrays.copyOf(first, totalLength);
int offset = first.length;
for (T[] array : rest) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
private static Pattern pattern = Pattern.compile("[0-9a-zA-Z]");
/**
* 判断从字符串msg获取的key值是否为单词 , index为key在msg中的索引值
*
* @return
*/
private boolean isWordChar(String msg, String key, int index) {
// 必须确定key是一个单词............................
if (index != 0) { // 判断key前面一个字符
char preCh = msg.charAt(index - 1);
Matcher match = pattern.matcher(preCh + "");
if (match.matches()) {
return true;
}
}
// 判断key后面一个字符
char nextCh = msg.charAt(index + key.length());
Matcher match = pattern.matcher(nextCh + "");
if (match.matches()) {
return true;
}
return false;
}
/**
* 获取value值的开始位置
*
* @param msg 要查找的字符串
* @param valueStart 查找的开始位置
* @return
*/
private int getValueStartIndex(String msg, int valueStart) {
// 寻找值的开始位置.................................
do {
char ch = msg.charAt(valueStart);
if (ch == ':' || ch == '=') { // key与 value的分隔符