User Tools

Site Tools


java-example:masktostring

MaskToStringBuilder

package com.xiaosq.common;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Map;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
 
/**
 * @author Morgan.L
 * @version 1.0
 * @date 2019/7/9 17:10
 */
public class MaskToStringBuilder extends ReflectionToStringBuilder {
 
    public MaskToStringBuilder(Object object) {
        super(object);
    }
 
    public MaskToStringBuilder(Object object, ToStringStyle style) {
        super(object, style);
    }
 
    public MaskToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer) {
        super(object, style, buffer);
    }
 
    public MaskToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer, Class reflectUpToClass, boolean outputTransients, boolean outputStatics) {
        super(object, style, buffer, reflectUpToClass, outputTransients, outputStatics);
    }
 
    @Override
    protected Object getValue(Field field) throws IllegalArgumentException, IllegalAccessException {
        for (Annotation annotation : field.getDeclaredAnnotations()) {
            if (annotation instanceof SensitiveF && field.get(this.getObject()) != null) {
                SensitiveF.Type type = ((SensitiveF) annotation).type();
                if (String.class.equals(field.get(this.getObject()).getClass())) {
                    String fieldValue = (String) field.get(this.getObject());
 
                    return MaskUtil.doMask(type, fieldValue);
 
                    //注意在使用的时候,List中必须是String,而不能是其他对象,不然会抛错
                } else if (field.get(this.getObject()) instanceof Iterable) {
 
                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append('[');
                    boolean appended = false;
 
                    for (String fieldValue : (Iterable<String>) field.get(this.getObject())) {
                        if (appended) {
                            stringBuilder.append(',');
                        }
                        stringBuilder.append(MaskUtil.doMask(type, fieldValue));
                        appended = true;
                    }
                    stringBuilder.append(']');
                    return stringBuilder.toString();
 
                    //注意在使用的时候,Map的key或者value不是String的时候就不做任何掩码操作
                } else if (field.get(this.getObject()) instanceof Map) {
 
                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append('{');
                    boolean appended = false;
                    for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) field.get(this.getObject())).entrySet()) {
                        if (appended) {
                            stringBuilder.append(',');
                        }
 
                        if (entry.getKey() != null && entry.getKey() instanceof String) {
                            String fieldValue = (String) entry.getKey();
                            stringBuilder.append(MaskUtil.doMask(type, fieldValue));
                        } else {
                            stringBuilder.append((String) entry.getKey());
                        }
 
                        stringBuilder.append('=');
 
                        if (entry.getValue() != null && entry.getValue() instanceof String) {
                            String fieldValue = (String) entry.getValue();
                            stringBuilder.append(MaskUtil.doMask(type, fieldValue));
                        } else {
                            stringBuilder.append((String) entry.getValue());
                        }
                        appended = true;
                    }
                    stringBuilder.append('}');
                    return stringBuilder.toString();
                }
            }
        }
        return super.getValue(field);
    }
}

SensitiveF

package com.xiaosq.common;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * @author Morgan.L
 * @version 1.0
 * @date 4/9/2020 4:15 PM
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
public @interface SensitiveF {
 
    enum Type {PhoneNo, Password, IdNo, BankCardNo, RealName}
 
    Type type();
}

MaskUtil

package com.xiaosq.common;
 
import com.spcredit.core.util.SensitiveF;
import org.apache.commons.lang3.StringUtils;
 
public class MaskUtil {
 
    private static int[] generateMaskRule(SensitiveF.Type type, String fieldValue) {
        //第一个表示前面需显示的长度 prefixShowLength,第二表示后面需显示的长度 suffixShowLength
        //默认全部掩码,所以两个值都是0
        int[] result = {0, 0};
 
        if (SensitiveF.Type.PhoneNo.equals(type)
                || SensitiveF.Type.IdNo.equals(type)
                || SensitiveF.Type.BankCardNo.equals(type)) {
            result[0] = 4;
            result[1] = 4;
 
        } else if (SensitiveF.Type.RealName.equals(type)) {
            if (StringUtils.isNotBlank(fieldValue)) {
                if (fieldValue.length() > 2) {
                    result[0] = 1;
                    result[1] = 1;
                } else {
                    result[0] = 1;
                    result[1] = 0;
                }
            }
        } else {
            //没有写SensitiveField.Type.Password的判断,因为安全从严的角度:默认全部掩码。
        }
        return result;
    }
 
    /**
     * liaowenyue:此方法只用于掩码中间字符。如果要掩码两边的字符,请重新加方法,或者有其他规则的话
     * fieldValue 需要掩码的字段的值
     * prefixShowLength 前面需要显示的字符数
     * type 敏感数据类型
     */
    public static String doMask(SensitiveF.Type type, String fieldValue) {
        int[] maskRule = generateMaskRule(type, fieldValue);
        String maskStr = "*"; //默认用 * 填充字符。
 
        if (StringUtils.isBlank(fieldValue)) {
            return fieldValue;
        }
 
        int showLength = maskRule[0] + maskRule[1];
        if (showLength < fieldValue.length()) {
            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < fieldValue.length(); j++) {
                if (j < maskRule[0]) {
                    sb.append(fieldValue.charAt(j));
                    continue;
                }
                if (j > (fieldValue.length() - 1 - maskRule[1])) {
                    sb.append(fieldValue.charAt(j));
                    continue;
                }
                sb.append(maskStr);
            }
            return sb.toString();
        } else {
            return fieldValue;
        }
    }
}
java-example/masktostring.txt · Last modified: 2021/12/20 09:24 by morgan0329

Except where otherwise noted, content on this wiki is licensed under the following license: 沪ICP备12046235号-2
Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki