使用自定义Json注解实现输出日志字段脱敏

以下是使用自定义Json注解实现输出日志字段脱敏的完整攻略。

什么是Json注解

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写。在Java应用程序中,我们通常使用Jackson或者Gson等库将Java对象序列化为JSON格式。而Json注解则是在Java对象中添加特定标记以控制序列化和反序列化过程的一种方式。

为什么需要Json注解

在某些情况下,我们需要对输出的字段进行脱敏,比如手机号、身份证号等敏感信息。如果我们直接将对象序列化为JSON格式输出,这些敏感信息就暴露给了外界。因此,有必要使用Json注解对输出的字段进行脱敏。

如何使用自定义Json注解实现输出日志字段脱敏

  1. 定义自定义注解

我们先定义一个自定义注解 @SensitiveProperty,用于标记需要脱敏的字段。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveProperty {
}
  1. 定义Jackson的自定义序列化程序

我们定义一个SensitivePropertySerializer用于实现自定义的序列化逻辑。该序列化程序会在序列化时遍历Java对象的所有属性,并判断哪些属性被标记为@SensitiveProperty,将其进行脱敏处理。

public class SensitivePropertySerializer extends JsonSerializer<Object> {

    private static final String SENSITIVE_MASK = "******";

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        PropertyFilter filter = new SimpleBeanPropertyFilter() {
            @Override
            public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer) throws Exception {
                if (!writer.isFiltered()) {
                    if (writer.getAnnotation(SensitiveProperty.class) != null) {
                        jgen.writeStringField(writer.getName(), SENSITIVE_MASK);
                    } else {
                        writer.serializeAsField(pojo, jgen, provider);
                    }
                }
            }
        };

        ObjectMapper mapper = new ObjectMapper();
        mapper.setFilterProvider(new SimpleFilterProvider().addFilter("myFilter", filter));
        mapper.writerWithDefaultPrettyPrinter().writeValue(gen, value);
        gen.writeEndObject();
    }
}

  1. 定义Java对象

在Java对象中添加自定义注解@SensitiveProperty来标记需要脱敏的属性。

public class User {
    private int id;
    private String name;
    private String phone;
    private String address;

    @SensitiveProperty
    private String idCard;

    // getter和setter方法省略
}

  1. 序列化Java对象

我们使用Jackson将Java对象序列化为JSON格式,并实现脱敏。

public class Main {
    public static void main(String[] args) {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        user.setPhone("18312345678");
        user.setAddress("北京市海淀区");
        user.setIdCard("110101199001011234");

        SimpleFilterProvider filterProvider = new SimpleFilterProvider();
        filterProvider.addFilter("myFilter", SimpleBeanPropertyFilter.filterOutAllExcept("id", "name", "phone", "address", "idCard"));

        ObjectMapper mapper = new ObjectMapper();
        mapper.setFilterProvider(filterProvider);
        try {
            String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
            System.out.println(jsonString);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

执行以上代码,控制台输出的JSON字符串如下所示:

{
  "id" : 1,
  "name" : "张三",
  "phone" : "18312345678",
  "address" : "北京市海淀区",
  "idCard" : "******"
}
  1. 使用自定义注解实现多种脱敏方式

除了像上面的例子一样使用固定的脱敏字符串,有时我们可能需要根据需求进行不同方式的脱敏。此时,我们可以在@SensitiveProperty注解中添加一个脱敏类型的参数。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveProperty {
    String type() default "default";
}

在序列化程序中判断注解中的脱敏类型字段,进行不同的脱敏方式。

public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
    // ...
    String rawValue = String.valueOf(propertyValue);
    if ("default".equals(sensitiveType)) {
        jgen.writeStringField(name, SENSITIVE_MASK);
    } else if ("name".equals(sensitiveType)) {
        jgen.writeStringField(name, rawValue.substring(0, 1) + SENSITIVE_MASK);
    } else if ("phone".equals(sensitiveType)) {
        jgen.writeStringField(name, rawValue.substring(0, 3) + SENSITIVE_MASK + rawValue.substring(7));
    } else if ("idCard".equals(sensitiveType)) {
        jgen.writeStringField(name, rawValue.substring(0, 4) + SENSITIVE_MASK + rawValue.substring(14));
    } else {
        writer.serializeAsField(pojo, jgen, provider);
    }
}

我们可以使用上面定义的注解@SensitiveProperty来标记需要脱敏的字段以及不同的脱敏方式。

public class User {
    private int id;

    @SensitiveProperty(type = "name")
    private String name;

    @SensitiveProperty(type = "phone")
    private String phone;

    private String address;

    @SensitiveProperty(type = "idCard")
    private String idCard;

    // getter和setter方法省略
}

执行以上代码,输出的JSON字符串如下所示:

{
  "id" : 1,
  "name" : "张******",
  "phone" : "183****5678",
  "address" : "北京市海淀区",
  "idCard" : "1101******1234"
}

这样,我们利用自定义注解@SensitiveProperty和Jackson的自定义序列化程序就实现了输出日志字段脱敏的功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用自定义Json注解实现输出日志字段脱敏 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Data Source与数据库连接池简介(JDBC简介)

    Data Source与数据库连接池简介 什么是Data Source? 在Java中,使用JDBC进行数据库操作时需要通过连接参数来获取数据库连接,而数据连接参数的获取和管理将会非常复杂。于是,为了解决这个问题,Java2引入了一种新的数据源管理机制:Data Source。 Data Source指的是一个应用程序和一个JDBC驱动程序之间的接口。在Ja…

    Java 2023年5月20日
    00
  • SpringBoot整合Sharding-JDBC实现MySQL8读写分离

    下面我将详细讲解如何使用SpringBoot整合Sharding-JDBC实现MySQL8读写分离的过程,包括环境搭建、配置文件编写、代码实现和示例说明等: 一、环境搭建 使用MySQL8搭建读写分离环境并创建两个数据库:sharding_db_0和sharding_db_1,分别对应写库和读库。 在maven中引入Sharding-JDBC和相关依赖: x…

    Java 2023年6月16日
    00
  • Linux 下java jps命令使用解析详解

    Linux 下 java jps 命令使用解析详解 Java 程序在运行的时候,如果需要查看当前 Java 进程,可以使用 jps 命令。本文通过详细介绍各个参数以及示例,帮助用户更好地使用 jps 命令。 为什么要使用 jps 命令 jps 命令用于查看当前 Java 进程的进程 ID (PID) 以及启动类的类名 (fully qualified nam…

    Java 2023年5月26日
    00
  • Java新手环境搭建 Tomcat安装配置教程

    Java新手环境搭建 Tomcat安装配置教程 如果你是Java新手,想要在自己的电脑上搭建开发环境,并安装配置Tomcat服务器,本教程将会是一个非常详细的指导,涵盖了从Java环境搭建到Tomcat服务器配置的全过程。 1. Java环境搭建 1.1 下载Java Development Kit(JDK) 首先,你需要从Oracle官网下载Java De…

    Java 2023年5月20日
    00
  • Spring中的事务管理如何配置

    Spring提供了声明式事务管理和编程式事务管理两种方式。本文主要介绍Spring中的声明式事务管理的配置方法。 1. 配置数据源及事务管理器 首先需要配置数据源,这里以MySQL为例,配置方法如下: <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDa…

    Java 2023年6月3日
    00
  • Java实战之酒店人事管理系统的实现

    Java实战之酒店人事管理系统的实现 介绍 本篇攻略将详细介绍如何使用Java语言实现一个酒店人事管理系统。该系统主要功能包括员工信息的录入、查询、修改和删除,以及工资和考勤等数据的统计。开发该系统需要掌握Java语言、MySQL数据库和Java GUI编程等技术。 准备工作 在开始开发之前,需要完成以下准备工作: 安装JDK和Eclipse IDE。 安装…

    Java 2023年6月16日
    00
  • Spring boot实现一个简单的ioc(2)

    针对“Spring boot实现一个简单的ioc(2)”这个话题,下面是完整攻略: 步骤一:创建Maven项目 首先我们需要创建一个Maven项目,这里以使用Intellij IDEA为例: 在Intellij IDEA中选择“Create New Project”; 选择“Maven”项目,并输入项目名称和路径,点击“Next”; 选择适合的“Group”…

    Java 2023年5月19日
    00
  • 从零开始让你的Spring Boot项目跑在Linux服务器

    首先我们来讲解“从零开始让你的Spring Boot项目跑在Linux服务器”的攻略。 准备工作 在将Spring Boot项目跑在Linux服务器之前,需要先确保我们已经满足以下条件: 已经有一台Linux服务器,并且可以通过SSH连接; 已经安装好Java Runtime Environment(JRE); 已经下载好我们的Spring Boot项目并打…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部