iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java利用Jackson序列化实现数据脱敏
  • 598
分享到

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

2024-04-02 19:04:59 598人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

几天前使用了Jackson对数据的自定义序列化。突发灵感,利用此方法来简单实现接口返回数据脱敏,故写此文记录。 核心思想是利用Jackson的StdSerializer,@JSONS

几天前使用了Jackson对数据的自定义序列化。突发灵感,利用此方法来简单实现接口返回数据脱敏,故写此文记录。

核心思想是利用Jackson的StdSerializer,@JSONSerialize,以及自己实现的数据脱敏过程。

使用效果如下:

首先在需要进行脱敏的VO字段上面标注相关脱敏注解

调用接口即可看到脱敏效果

实现过程如下:

1. 定义脱敏的过程实现



public interface Desensitization<T> {

    
    T desensitize(T target);

}

比如具体的手机号脱敏器实现


import com.GitHub.Symbol;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class PhoneDesensitization implements StringDesensitization {

    
    private static final Pattern DEFAULT_PATTERN = Pattern.compile("(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}");

    
    @Override
    public String desensitize(String target) {
        Matcher matcher = DEFAULT_PATTERN.matcher(target);
        while (matcher.find()) {
            String group = matcher.group();
            target = target.replace(group, group.substring(0, 3) + Symbol.getSymbol(4, Symbol.STAR) + group.substring(7, 11));
        }
        return target;
    }
}

2.定义脱敏注解,并指明了使用的序列化器,注解中声明了使用的脱敏器实现


package com.github.annotation;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.jsonSerialize;
import com.github.desensitization.Desensitization;
import com.github.serializer.ObjectDesensitizeSerializer;

import java.lang.annotation.*;


@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = ObjectDesensitizeSerializer.class)
@Documented
public @interface Desensitize {
    
    @SuppressWarnings("all")
    Class<? extends Desensitization<?>> desensitization();
}

3. 实现定义的序列化器


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 com.github.Symbol;
import com.github.annotation.Desensitize;
import com.github.desensitization.Desensitization;
import com.github.desensitization.DesensitizationFactory;
import com.github.desensitization.StringDesensitization;

import java.io.IOException;


public class ObjectDesensitizeSerializer extends StdSerializer<Object> implements ContextualSerializer {

    private transient Desensitization<Object> desensitization;

    protected ObjectDesensitizeSerializer() {
        super(Object.class);
    }

    public Desensitization<Object> getDesensitization() {
        return desensitization;
    }

    public void setDesensitization(Desensitization<Object> desensitization) {
        this.desensitization = desensitization;
    }

    @Override
    public JsonSerializer<Object> createContextual(SerializerProvider prov, BeanProperty property) {
        Desensitize annotation = property.getAnnotation(Desensitize.class);
        return createContextual(annotation.desensitization());
    }

    @SuppressWarnings("unchecked")
    public JsonSerializer<Object> createContextual(Class<? extends Desensitization<?>> clazz) {
        ObjectDesensitizeSerializer serializer = new ObjectDesensitizeSerializer();
        if (clazz != StringDesensitization.class) {
            serializer.setDesensitization((Desensitization<Object>) DesensitizationFactory.getDesensitization(clazz));
        }
        return serializer;
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        Desensitization<Object> objectDesensitization = getDesensitization();
        if (objectDesensitization != null) {
            try {
                gen.writeObject(objectDesensitization.desensitize(value));
            } catch (Exception e) {
                gen.writeObject(value);
            }
        } else if (value instanceof String) {
            gen.writeString(Symbol.getSymbol(((String) value).length(), Symbol.STAR));
        } else {
            gen.writeObject(value);
        }
    }
}

4.代码的设计说明

完整代码可见 : https://github.com/EalenXie/jackson-desensitize

另附 基于Logback的日志脱敏方案(笔者认为这可能是全网最简单快捷的)

原理是利用Logback的自定义日志转换器ClassicConverter

1. 自定义脱敏日志转换器


import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import com.github.desensitization.EmailDesensitization;
import com.github.desensitization.IDCardDesensitization;
import com.github.desensitization.PhoneDesensitization;
import com.github.desensitization.StringDesensitization;

import java.util.ArrayList;
import java.util.List;



public class LogbackDesensitizeConverter extends ClassicConverter {

    protected static final List<StringDesensitization> DESENSITIZATION_LIST = new ArrayList<>();

    static {
        // 手机号脱敏
        DESENSITIZATION_LIST.add(new PhoneDesensitization());
        // 邮箱脱敏
        DESENSITIZATION_LIST.add(new EmailDesensitization());
        // 身份证脱敏
        DESENSITIZATION_LIST.add(new IDCardDesensitization());
    }

    @Override
    public String convert(ILoggingEvent event) {
        String content = event.getMessage();
        try {
            for (StringDesensitization desensitization : DESENSITIZATION_LIST) {
                content = desensitization.desensitize(content);
            }
        } catch (Exception e) {
            // ig
        }
        return content;
    }
}

2. 启动类为PatternLayout的静态变量defaultConverterMap新增此自定义转换器


import ch.qos.logback.classic.PatternLayout;
import com.github.filter.LogbackDesensitizeConverter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;


@EnableDiscoveryClient
@SpringBootApplication
public class apiGatewayApplication {
    public static void main(String[] args) {
        // 日志处理方案 新增一个Logback的日志脱敏转换器
        PatternLayout.defaultConverterMap.put("m", LogbackDesensitizeConverter.class.getName());
        SpringApplication.run(ApiGatewayApplication.class, args);
    }
}

启动后可以看到日志脱敏效果。

到此这篇关于利用Jackson序列化实现数据脱敏的文章就介绍到这了,更多相关Jackson序列化数据脱敏内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java利用Jackson序列化实现数据脱敏

本文链接: https://www.lsjlt.com/news/137934.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作