在开发中有时候需要打印一些对象的属性值, 但是其中含有一些敏感字段, 不能打印明文而是需要脱敏打印,写了一个工具, 可以将对象转换成JSON字符串,并且可以指定要脱敏的字段名称 package com. visy. utils ; import cn. hutool. core. util. ObjectUtil ; import com. alibaba. fastjson. JSON; import com. alibaba. fastjson. JSONObject ; import com. alibaba. fastjson. serializer. SerializerFeature ; import java. util. Arrays ; public class LogUtil { /** * 安全的JSON字符串转换(可脱敏) * @param obj 待序列化对象 * @param fieldNames 待脱敏的字段名称 * @return JSON字符串 */ public static String toJsonSafety ( Object obj, String . . . fieldNames) { if ( fieldNames== null || fieldNames. length== 0 ) { return toJson ( obj) ; } JSONObject jsonObject= ( JSONObject ) JSON. toJSON ( obj) ; for ( String fieldName: fieldNames) { Object value= jsonObject. get ( fieldName) ; if ( ObjectUtil . isNotNull ( value) ) { jsonObject. put ( fieldName, mask ( value. toString ( ) ) ) ; } } return toJson ( jsonObject) ; } private static String toJson ( Object obj) { return JSON. toJSONString ( obj, SerializerFeature. WriteMapNullValue ) ; } /** * 字符串脱敏方法(自动计算并隐藏部分字符) * @param value 待脱敏的字符串 * @return 脱敏后的字符串 */ public static String mask ( String value) { if ( value== null || value. isEmpty ( ) ) { return value; } int length= value. length ( ) , halfLength= length/ 2 ; if ( halfLength<= 1 ) { // 1 ~ 3 个字符, 全部脱敏 return createRepeatedString ( '*' , length) ; } else { // >= 4 个字符, 前后各保留1/4 个字符 int beforeLength= halfLength/ 2 ; return mask ( value, '*' , beforeLength, halfLength- beforeLength) ; } } /** * 数据脱敏方法 * @param value 待脱敏的原始数据 * @param ch 脱敏占位字符 * @param beforeLength 前保留字符数 * @param afterLength 后保留字符数 * @return 脱敏后的数据 */ public static String mask ( String value, char ch, int beforeLength, int afterLength) { // 空值安全检查 if ( value== null || value. isEmpty ( ) ) { return value; } final int length= value. length ( ) , leastLength= beforeLength+ afterLength; // 长度小于等于leastLength位,全部脱敏 if ( length<= leastLength) { if ( length<= afterLength) { // 剩余长度小于等于afterLength,全部脱敏 return createRepeatedString ( ch, length) ; } // 剩余长度大于afterLength,只脱敏前length-afterLength位 return createRepeatedString ( ch, length- afterLength) + value. substring ( length- afterLength) ; } return value. substring ( 0 , beforeLength) + createRepeatedString ( ch, length- leastLength) + value. substring ( length- afterLength) ; } /** * 创建重复字符的字符串 * @param ch 要重复的字符 * @param count 重复次数 * @return 重复字符组成的字符串 */ private static String createRepeatedString ( char ch, int count) { if ( count<= 0 ) { return "" ; } char [ ] chars= new char [ count] ; Arrays . fill ( chars, ch) ; return new String ( chars) ; } } public class LogUtilTest { public static void main ( String [ ] args) { User user= new User ( ) ; user. setName ( "张三" ) ; user. setAge ( 22 ) ; user. setIdCard ( "320381198812252138" ) ; //打印结果:{"idCard":"3203*********52138","name":"张三","age":22} System . out. println ( LogUtil . toJsonSafety ( user, "idCard" ) ) ; } @Data static class User { private String name; private Integer age; private String idCard; } }