利用Jackson序列化实现数据脱敏

@JsonSerialize

先看下jackson的@JsonSerialize注解。

@JsonSerialize是jackson提供自定义序列化方法的注解,它有个using 属性,指定自定义序列化的执行类;

例如:
先自定义一个序列化类

public class OptimizedBooleanSerializer extends JsonSerializer<Boolean> {

    @Override
    public void serialize(Boolean aBoolean, JsonGenerator jsonGenerator, 
        SerializerProvider serializerProvider) 
    throws IOException, JsonProcessingException {

        if(aBoolean){
            jsonGenerator.writeNumber(1);
        } else {
            jsonGenerator.writeNumber(0);
        }
    }
}

@JsonSerialize注解的Java类示例

public class PersonVo {

    public long   personId = 0;
    public String name ="John";

    @JsonSerialize(using = OptimizedBooleanSerializer.class)
    public boolean enabled = false;
}

我们知道,springMVC是通过jackson这个序列化框架,当响应头的Content-Type是application/json;charset=UTF-8时,对返回的vo转换为json对象;所以,利用jackson的注解,这样就可以实现脱敏,下面我们对这个注解做一层封装。

升级

1.自定义序列化类,每当有需要脱敏的字段,例如,人名,邮箱,手机号等等,我们就创建一个这样的类,主要是制定一种脱敏的规则。

public class EmailDesensitization extends JsonSerializer<String> {

    /**
     * 邮箱正则(半匹配)
     */
    private static final Pattern DEFAULT_PATTERN = Pattern.compile("([A-Za-z0-9_\\-.])+@([A-Za-z0-9_\\-.])+\\.([A-Za-z]{2,4})");

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        Matcher matcher = DEFAULT_PATTERN.matcher(value);
        while (matcher.find()) {
            String group = matcher.group();
            int l = group.lastIndexOf("@");
            value = value.replace(group, group.substring(0,2) + Symbol.getSymbol(l - 2, Symbol.STAR) + group.substring(l));
        }

        gen.writeString(value);
    }

}

2.定义脱敏注解
@JacksonAnnotationsInside 表示将注解捆绑;当我们在字段注解@EmailDesensitize ,等价于@JsonSerialize(using = EmailDesensitization.class);

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = EmailDesensitization.class)
@Documented
public @interface EmailDesensitize {
}

Symbol类

public class Symbol {


    /**
     * '*'脱敏符
     */
    public static final String STAR = "*";

    private Symbol() {

    }

    /**
     * 获取符号
     *
     * @param number 符号个数
     * @param symbol 符号
     */
    public static String getSymbol(int number, String symbol) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < number; i++) {
            sb.append(symbol);
        }
        return sb.toString();
    }
}

3.vo字段加注解

public class PersonVo {

    private String name;

    @JsonProperty("someEmail")
    @EmailDesensitize
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

4.测试

@RestController
public class TestController {

    @ResponseBody
    @GetMapping("/getPerson")
    public PersonVo getPerson() {
        PersonVo vo = new PersonVo();
        vo.setName("强强");
        vo.setEmail("13355782547@qq.com");
        return vo;
    }

}

5.结果

{"name":"强强","someEmail":"13********@qq.com"}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容