首页 > 其他分享 >Jackson的@JsonSubTypes注解

Jackson的@JsonSubTypes注解

时间:2024-12-16 21:01:10浏览次数:5  
标签:username Jackson String JsonSubTypes User 注解 序列化 public Guest

1. 概述

Jackson 是一个关键的Java库,擅长将Java对象转换为JSON格式以及反向操作。在Java中处理对象层次结构和多态性时,将JSON反序列化回正确的子类型可能会变得具有挑战性。Jackson的@JsonSubTypes注解有助于解决这个问题。

@JsonSubTypes 注解概览

@JsonSubTypes注解与@JsonTypeInfo注解一起使用,用于指定给定父类型的子类型。这确保了Jackson可以根据包含的元数据将JSON数据反序列化为适当的子类型。

2. 开发步骤

  1. 启动一个新的Maven项目。
  2. 添加必要的Jackson依赖项。
  3. 创建User超类,使用@JsonSubTypes指定子类型,并应用@JsonTypeInfo注解。
  4. 实现一个单独的类来处理序列化过程。
  5. 构建一个主类来展示序列化和反序列化过程。

3. 创建Maven项目

创建简单Maven项目有几种方式:

  • 使用命令行界面创建简单的Maven项目
  • 使用Eclipse IDE创建简单的Maven项目
  • 使用IntelliJ IDEA创建简单的Maven项目

4. Maven依赖

打开pom.xml文件,并添加以下Jackson数据绑定依赖项:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.0</version>
</dependency>

5. 示例代码

以用户管理系统为例,我们来看具体实现:

// User.java
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "userType")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Admin.class, name = "admin"),
        @JsonSubTypes.Type(value = Guest.class, name = "guest")
})
public abstract class User {
    private String username;

    // Constructors, getters, setters...

    public User() {}

    public User(String username) {
        this.username = username;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

class Admin extends User {
    private String adminRole;

    // Constructors, getters, setters...

    public Admin() {}

    public Admin(String username, String adminRole) {
        super(username);
        this.adminRole = adminRole;
    }

    public String getAdminRole() {
        return adminRole;
    }

    public void setAdminRole(String adminRole) {
        this.adminRole = adminRole;
    }
}

class Guest extends User {
    private boolean hasTempAccess;

    // Constructors, getters, setters...

    public Guest() {}

    public Guest(String username, boolean hasTempAccess) {
        super(username);
        this.hasTempAccess = hasTempAccess;
    }

    public boolean isHasTempAccess() {
        return hasTempAccess;
    }

    public void setHasTempAccess(boolean hasTempAccess) {
        this.hasTempAccess = hasTempAccess;
    }
}

// JsonSerializer.java
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonSerializer {
    public static String serializeToJson(User user) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(user);
    }

    public static User deserializeFromJson(String json) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(json, User.class);
    }
}

// MainClass.java
public class MainClass {
    public static void main(String[] args) {
        User guest = new Guest("JohnDoe", true);
        try {
            String json = JsonSerializer.serializeToJson(guest);
            System.out.println("Serialized JSON: " + json);
            User deserializedUser = JsonSerializer.deserializeFromJson(json);
            System.out.println("Deserialized User: " + deserializedUser.getUsername());
            if (deserializedUser instanceof Guest) {
                System.out.println("Is Guest with Temp Access: " + ((Guest) deserializedUser).isHasTempAccess());
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

输出:

Serialized JSON: {"userType":"guest","username":"JohnDoe","hasTempAccess":true}
Deserialized User: JohnDoe
Is Guest with Temp Access: true

代码解释:

  • User 类是一个抽象超类,有两个具体的子类:AdminGuest
  • 使用@JsonSubTypes注解指定了这些子类型。
  • @JsonTypeInfo注解指示了序列化期间应如何包含子类型信息。
  • JsonSerializer 类展示了使用Jackson的ObjectMapper进行序列化和反序列化的逻辑。
  • MainClass 展示了创建一个Guest实例的过程,将其序列化为JSON,然后再次反序列化回User对象,并检查其是否为Guest类型以及是否有临时访问权限。

6. 结论

Jackson的@JsonSubTypes注解使得多态Java类型的序列化和反序列化变得更加流畅。通过明确地指定子类型,开发人员可以在应用程序中确保从JSON到Java对象转换时的类型安全性和一致性。

标签:username,Jackson,String,JsonSubTypes,User,注解,序列化,public,Guest
From: https://blog.csdn.net/woshichenpi/article/details/144329592

相关文章

  • Jackson@JsonTypeInfo 注解
    1.概述Jackson是一个强大的Java库,以其将Java对象转换为JSON格式及反向操作的能力而闻名。在处理多态类型时,需要在序列化的JSON中包含类型信息以确保正确的反序列化。Jackson提供的@JsonTypeInfo注解帮助解决了这个挑战。@JsonTypeInfo注解概览@JsonTypeInfo注解用于指......
  • spock之Unroll注解的作用
    在Spock框架中,@Unroll 注解用于数据驱动测试(data-driventesting),它允许将一个数据驱动的规范方法拆分为多个独立的测试用例,并为每个用例生成详细的描述。这对于调试和报告非常有用,因为它能清晰地展示每个用例的执行情况。适用场景数据驱动测试:当你有一组输入数据集,并希望......
  • springboot常用注解
    1.@Configuration标注在类上,表明该类是springboot中配置类2.@Bean与@Configuration配合使用,标注在方法上,表明是配置类中的组件3.@Import导入组件,例子@Import({User.class,DBHelper.class}),给容器中自动建出这两个类型的组件,默认组件的名字是全类名4.@Conditional条件装配:......
  • 18.Java Lambda 表达式(Lambda 表达式练习与原理分析、@FunctionalInterface 注解)
    一、问题引入1、问题案例开启一个新的线程,指定线程要执行的任务newThread(newRunnable(){publicvoidrun(){System.out.println("HelloWorld");}}).start();2、问题分析Thread类需要一个Runnable接口作为参数,其中抽象方法run是用来指......
  • Jackson @JsonIgnore 注解
    1.概述Jackson是一个广泛使用的Java库,它允许轻松地将Java对象序列化为JSON以及从JSON反序列化回Java对象。Jackson库提供的其中一个注解是@JsonIgnore。这个注解用于在序列化和反序列化过程中忽略特定的属性。这在转换JSON与Java对象之间时隐藏或省略敏感或不必要的数据......
  • Jackson @JsonProperty 注解
    1.概述Jackson是一个流行的Java库,用于将Java对象转换为JSON格式以及从JSON反序列化回Java对象。一种常见的需求是在序列化为JSON或从JSON反序列化时自定义字段的命名。Jackson的@JsonProperty注解正好满足了这一需求。@JsonProperty注解概览@JsonProperty注解用于......
  • 注解:@FunctionalInterface函数式接口
    @FunctionalInterface是Java8引入的一个标记型注解,用于声明一个接口是函数式接口(FunctionalInterface)。函数式接口是指只有一个抽象方法的接口,这样的接口可以被用作Lambda表达式的类型。使用@FunctionalInterface注解有助于确保接口符合函数式接口的定义,并且在编译时......
  • 【代码设计】Java 用注解简洁明了的标注数据筛选特性
    基础设计默认值:仅包含正常状态数据,例如账户:不包含离职账户的正常账户即为deletedData=false,wantsEnabled=true,wantsDisabled=false场景举例:场景一:正常的只展示正常的账户,则为默认的情况场景二:只搜索不正常的已经删除的账户,则与上一条完全相反,则为wantsEnabled=......
  • testng常用注解
    1.测试用例注解@Test标记一个类或方法作为测试的一部分。常用属性:    @Test(enabled=false)忽略测试,标识它不是一个测试用例    @Test(priority=-1)//priority默认值0,改变用例执行顺序值越小优先级越高    @Test(invocationCount=2)//测试用例执行次......
  • 技术框架中MyBatis注解的学习
    MyBatis注解模式MyBatis两种映射模式MyBatis有两种SQL语句映射模式:一种是基于XML,一种是基于注解。在这之前,我们都是使用基于XML映射文件这种模式实现数据库的各种操作。这次,我打算使用MyBatis注解的方式重新实现之前的数据库操作。MyBatis注解与XML映射文件不同之......