package cn.lihu.jh.framework.desensitize.core.base.serializer; 
 | 
  
 | 
import cn.hutool.core.annotation.AnnotationUtil; 
 | 
import cn.hutool.core.lang.Singleton; 
 | 
import cn.hutool.core.util.ArrayUtil; 
 | 
import cn.hutool.core.util.ReflectUtil; 
 | 
import cn.hutool.core.util.StrUtil; 
 | 
import cn.lihu.jh.framework.desensitize.core.base.annotation.DesensitizeBy; 
 | 
import cn.lihu.jh.framework.desensitize.core.base.handler.DesensitizationHandler; 
 | 
import com.fasterxml.jackson.core.JsonGenerator; 
 | 
import com.fasterxml.jackson.databind.BeanProperty; 
 | 
import com.fasterxml.jackson.databind.JsonSerializer; 
 | 
import com.fasterxml.jackson.databind.SerializerProvider; 
 | 
import com.fasterxml.jackson.databind.ser.ContextualSerializer; 
 | 
import com.fasterxml.jackson.databind.ser.std.StdSerializer; 
 | 
import lombok.Getter; 
 | 
import lombok.Setter; 
 | 
  
 | 
import java.io.IOException; 
 | 
import java.lang.annotation.Annotation; 
 | 
import java.lang.reflect.Field; 
 | 
  
 | 
/** 
 | 
 * 脱敏序列化器 
 | 
 * 
 | 
 * 实现 JSON 返回数据时,使用 {@link DesensitizationHandler} 对声明脱敏注解的字段,进行脱敏处理。 
 | 
 * 
 | 
 * @author gaibu 
 | 
 */ 
 | 
@SuppressWarnings("rawtypes") 
 | 
public class StringDesensitizeSerializer extends StdSerializer<String> implements ContextualSerializer { 
 | 
  
 | 
    @Getter 
 | 
    @Setter 
 | 
    private DesensitizationHandler desensitizationHandler; 
 | 
  
 | 
    protected StringDesensitizeSerializer() { 
 | 
        super(String.class); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) { 
 | 
        DesensitizeBy annotation = beanProperty.getAnnotation(DesensitizeBy.class); 
 | 
        if (annotation == null) { 
 | 
            return this; 
 | 
        } 
 | 
        // 创建一个 StringDesensitizeSerializer 对象,使用 DesensitizeBy 对应的处理器 
 | 
        StringDesensitizeSerializer serializer = new StringDesensitizeSerializer(); 
 | 
        serializer.setDesensitizationHandler(Singleton.get(annotation.handler())); 
 | 
        return serializer; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    @SuppressWarnings("unchecked") 
 | 
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException { 
 | 
        if (StrUtil.isBlank(value)) { 
 | 
            gen.writeNull(); 
 | 
            return; 
 | 
        } 
 | 
        // 获取序列化字段 
 | 
        Field field = getField(gen); 
 | 
  
 | 
        // 自定义处理器 
 | 
        DesensitizeBy[] annotations = AnnotationUtil.getCombinationAnnotations(field, DesensitizeBy.class); 
 | 
        if (ArrayUtil.isEmpty(annotations)) { 
 | 
            gen.writeString(value); 
 | 
            return; 
 | 
        } 
 | 
        for (Annotation annotation : field.getAnnotations()) { 
 | 
            if (AnnotationUtil.hasAnnotation(annotation.annotationType(), DesensitizeBy.class)) { 
 | 
                value = this.desensitizationHandler.desensitize(value, annotation); 
 | 
                gen.writeString(value); 
 | 
                return; 
 | 
            } 
 | 
        } 
 | 
        gen.writeString(value); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 获取字段 
 | 
     * 
 | 
     * @param generator JsonGenerator 
 | 
     * @return 字段 
 | 
     */ 
 | 
    private Field getField(JsonGenerator generator) { 
 | 
        String currentName = generator.getOutputContext().getCurrentName(); 
 | 
        Object currentValue = generator.getCurrentValue(); 
 | 
        Class<?> currentValueClass = currentValue.getClass(); 
 | 
        return ReflectUtil.getField(currentValueClass, currentName); 
 | 
    } 
 | 
  
 | 
} 
 |