0

0

在Java关联关系中隐藏敏感数据:@JsonProperty详解

DDD

DDD

发布时间:2025-10-26 10:34:23

|

528人浏览过

|

来源于php中文网

原创

在Java关联关系中隐藏敏感数据:@JsonProperty详解

本文旨在探讨在java应用中,如何有效处理dto(数据传输对象)关联关系中敏感数据json序列化问题。我们将重点介绍如何利用jackson库的`@jsonproperty(access = jsonproperty.access.write_only)`注解,在嵌套对象中精确控制字段的可见性,从而在api响应中隐藏如密码、年龄等敏感信息,确保数据隐私和安全性。文章还将讨论其他实现方式及其适用场景与局限性。

在构建RESTful API时,我们经常会遇到需要将关联对象作为嵌套结构返回的情况。例如,一个BillsDto可能包含一个UserDto,而UserDto中又含有如用户名、密码或年龄等不应暴露给客户端的敏感信息。如何在不修改父级DTO(如BillsDto)的情况下,有效地隐藏这些嵌套对象的敏感字段,是API设计中一个常见的挑战。

核心方案:在嵌套DTO中控制序列化行为

解决此类问题的最直接且推荐的方法是,在包含敏感数据的DTO(即嵌套DTO)本身上应用序列化控制注解。Jackson库提供了强大的@JsonProperty注解,配合其access属性,可以精确地控制字段在序列化和反序列化过程中的行为。

当我们需要隐藏某个字段,使其在JSON响应中不出现,但允许在接收请求时进行反序列化(例如,创建或更新用户时),可以使用JsonProperty.Access.WRITE_ONLY。

以下是UserDto的示例,演示了如何隐藏username、password和age字段:

立即学习Java免费学习笔记(深入)”;

import com.fasterxml.jackson.annotation.JsonProperty;

public class UserDto {

    private String number_id;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String username;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String password;

    private String firstName;
    private String lastName;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String age;

    // Getter和Setter方法 (省略)
}

而BillsDto则无需做任何改动:

import java.util.Date;

public class BillsDto {

    private String numberBills;
    private double amount;
    private Date deadlinePayment;
    private UserDto user; // UserDto中的敏感字段将自动被隐藏

    // Getter和Setter方法 (省略)
}

当BillsDto对象被序列化为JSON时,其中嵌套的UserDto实例将根据其自身定义的@JsonProperty规则进行处理。这意味着username、password和age字段将不会出现在最终的JSON输出中。

为什么这是推荐的方法?

  1. 单一职责原则: UserDto作为用户数据的载体,其序列化策略应由自身定义。无论UserDto被哪个其他DTO引用,其敏感字段的隐藏策略都保持一致。
  2. 避免遗漏: 如果将序列化控制逻辑放在引用方(如BillsDto),那么每当UserDto被其他DTO(如OrderDto、CommentDto)引用时,都需要重复配置,容易造成遗漏,从而意外暴露敏感数据。
  3. 代码清晰与可维护性: 敏感字段的隐藏逻辑直接与其所属的DTO关联,代码更易于理解和维护。

备选方案:通过自定义序列化器在父DTO中控制

如果由于某些特殊限制,您无法修改嵌套的UserDto类,而只能在BillsDto中进行修改,那么可以考虑为UserDto实现一个自定义的JSON序列化器,并通过@JsonSerialize注解将其应用到BillsDto中的user字段上。

Stockimg AI
Stockimg AI

AI生成高质量图像、书籍封面、壁纸、海报、Logo、插画、艺术等

下载

例如:

  1. 创建自定义序列化器:

    import com.fasterxml.jackson.core.JsonGenerator;
    import com.fasterxml.jackson.databind.SerializerProvider;
    import com.fasterxml.jackson.databind.ser.std.StdSerializer;
    import java.io.IOException;
    
    public class UserDtoPublicSerializer extends StdSerializer {
    
        public UserDtoPublicSerializer() {
            this(null);
        }
    
        public UserDtoPublicSerializer(Class t) {
            super(t);
        }
    
        @Override
        public void serialize(UserDto user, JsonGenerator generator, SerializerProvider provider) throws IOException {
            generator.writeStartObject();
            generator.writeStringField("number_id", user.getNumber_id());
            generator.writeStringField("firstName", user.getFirstName());
            generator.writeStringField("lastName", user.getLastName());
            // 明确不写入 username, password, age
            generator.writeEndObject();
        }
    }
  2. 在BillsDto中应用自定义序列化器:

    import com.fasterxml.jackson.databind.annotation.JsonSerialize;
    import java.util.Date;
    
    public class BillsDto {
    
        private String numberBills;
        private double amount;
        private Date deadlinePayment;
    
        @JsonSerialize(using = UserDtoPublicSerializer.class)
        private UserDto user;
    
        // Getter和Setter方法 (省略)
    }

注意事项:

尽管此方法可行,但通常不推荐作为首选。它的主要缺点在于:

  • 分散控制: 敏感数据隐藏的逻辑分散在多个地方,增加了维护复杂性。
  • 易出错: 如果UserDto被其他DTO引用,很容易忘记应用自定义序列化器,从而导致敏感数据泄露。
  • 重复工作: 每当需要以不同方式序列化UserDto时,可能需要创建多个自定义序列化器。

最佳实践与总结

在处理Java中DTO关联关系的敏感数据序列化时,以下是一些最佳实践:

  1. 优先在源DTO中定义序列化策略: 始终尝试在包含敏感数据的DTO(如UserDto)内部使用@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)来控制字段的可见性。这遵循了单一职责原则,并确保了数据隐私策略的一致性。
  2. DTO分层设计: 对于复杂场景,可以考虑为不同的视图或API接口设计不同的DTO。例如,可以有一个UserPrivateDto(包含所有字段)和一个UserPublicDto(只包含非敏感字段),根据业务需求选择使用。这样可以更清晰地分离数据模型和API输出模型。
  3. 数据安全意识: 在设计API时,始终将数据安全放在首位。仔细审查每个API响应,确保没有意外暴露敏感信息。
  4. 利用Jackson的强大功能: Jackson库提供了丰富的注解和配置选项来控制JSON序列化和反序列化行为,如@JsonIgnore、@JsonInclude、@JsonFilter等,熟练掌握它们能帮助您构建健壮且安全的API。

通过上述方法,您可以有效地管理Java关联关系中敏感数据的JSON序列化,从而提升API的安全性与健壮性。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

837

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

741

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

736

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

399

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16926

2023.08.03

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

10

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.7万人学习

C# 教程
C# 教程

共94课时 | 7万人学习

Java 教程
Java 教程

共578课时 | 47.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号