java - Jackson - 仅序列化 Java Pojo 的列表属性中的对象 ID

标签 java json jackson jackson2

我想优化要在线发送的 json 数据。我的代码中有三个模型。这些是客户、发票和特定。

客户类别

@Data
public class Customer implements Serializable {

    private long customerId;

    private String name;

    private String taxId;

    private String phone;

    private String address;

    private String emailId;

    private Date created;

    private List<Invoice> invoices;
}

发票类

@Data
public class Invoice implements Serializable {

    private String invoiceId;

    private List<Particular> particulars;

    private Date invoiceDate;
}

特定类

@Data
public class Particular {
    private String item;
    private int quantity;
    private float tax;
    private int unitPrice;
}

我的测试代码:

@Test
    public void makeCustomerJsonWithInvoices() throws JsonProcessingException {
        Customer customer = new Customer();
        customer.setCustomerId(1234);
        customer.setName("Pawan");
        customer.setPhone("+918989898989");
        customer.setEmailId("<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9fecf0f2faebf7f6f1f8dfecf0f2faebf7f6f1f8b1fcf0f2" rel="noreferrer noopener nofollow">[email protected]</a>");
        customer.setAddress("Mumbai, India");
        customer.setTaxId("MQZ11DPS");
        customer.setCreated(new Date());

        Invoice invoice1 = new Invoice();
        invoice1.setInvoiceId("A-1");
        Particular particular1 = new Particular("abc", 1, 0, 12);
        Particular particular2 = new Particular("xyz", 2, 0, 20);
        invoice1.setInvoiceDate(new Date());
        invoice1.setParticulars(Arrays.asList(particular1, particular2));

        Particular particular3 = new Particular("mno", 2, 0, 15);
        Invoice invoice2 = new Invoice();
        invoice2.setInvoiceId("A-2");
        invoice2.setParticulars(Arrays.asList(particular3));
        invoice2.setInvoiceDate(new Date());
        customer.setInvoices(Arrays.asList(invoice1, invoice2));

        String value = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(customer);
        System.out.println(value);
    }

我在这里想要的是通过序列化发票来避免冗余,以便生成的 json 更加紧凑。这应该通过仅发送 InvoiceId 属性值而不是整个 Invoice 对象 json 来实现。

测试代码打印的内容:

{
  "customerId" : 1234,
  "name" : "Pawan",
  "taxId" : "MQZ11DPS",
  "phone" : "+918989898989",
  "address" : "Mumbai, India",
  "emailId" : "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bbc8d4d6decfd3d2d5dcfbc8d4d6decfd3d2d5dc95d8d4d6" rel="noreferrer noopener nofollow">[email protected]</a>",
  "created" : 1553243962038,
  "invoices" : [ {
    "invoiceId" : "A-1",
    "particulars" : [ {
      "item" : "abc",
      "quantity" : 1,
      "tax" : 0.0,
      "unitPrice" : 12
    }, {
      "item" : "xyz",
      "quantity" : 2,
      "tax" : 0.0,
      "unitPrice" : 20
    } ],
    "invoiceDate" : 1553243962038
  }, {
    "invoiceId" : "A-2",
    "particulars" : [ {
      "item" : "mno",
      "quantity" : 2,
      "tax" : 0.0,
      "unitPrice" : 15
    } ],
    "invoiceDate" : 1553243962039
  } ]
}

我想要打印什么:

{
  "customerId" : 1234,
  "name" : "Pawan",
  "taxId" : "MQZ11DPS",
  "phone" : "+918989898989",
  "address" : "Mumbai, India",
  "emailId" : "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ff8c90929a8b97969198bf8c90929a8b97969198d19c9092" rel="noreferrer noopener nofollow">[email protected]</a>",
  "created" : 1553243962038,
  "invoices" : [ {
    "invoiceId" : "A-1"
  }, {
    "invoiceId" : "A-2"
  } ]
}

@Datalombok用于生成 getter 和 setter 的注释。

我尝试向 Invoice 类添加 @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "invoiceId") 注释,但这不会改变输出。

请注意,我希望只有当发票作为子项传递到容器模型时才会发生这种序列化。如果我想独立发送发票,它应该序列化发票模型中的所有字段。我相信这是实现 RESTful WS 时的常见场景。

我需要为此编写客户序列化程序吗?

最佳答案

我可以通过以下方式修改 Customer 类来实现此目的。

@Data
public class Customer implements Serializable {

    private long customerId;

    private String name;

    private String taxId;

    private String phone;

    private String address;

    private String emailId;

    private Date created;

    @JsonIdentityInfo(generator= ObjectIdGenerators.PropertyGenerator.class, property="invoiceId")
    @JsonIdentityReference(alwaysAsId=true)
    private List<Invoice> invoices;
}

答案的灵感来自https://stackoverflow.com/a/17583175/1365340

有了这个,我可以生成带有发票 ID 列表的 Customer json。单独序列化时,Invoice 对象会从 json 中的所有字段获取所有值。

关于java - Jackson - 仅序列化 Java Pojo 的列表属性中的对象 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55295909/

相关文章:

java - 是否可以判断请求JSON中是否存在参数

java - 从 Class<T> 转换为 TypeReference<T>

java - 如何在多边形内添加JLabel?

java.lang.NoClassDefFoundError : io. reactivex.Flowable

java - 是否可以通过使用单个 volatile 来防止乱序执行

javascript - "[Error] ReferenceError: Can' t 查找变量 : data"when trying to get JSON data with AJAX/jQuery request

javascript - Express.js POST req.body 为空

java - 在 Mule 中测试子流

c# - 在 javascript 中使用 c# 类对象

java - 如何从 Java 中的 URL 读取 JSON 数据?