我想优化要在线发送的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("something@something.com");
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" : "something@something.com",
"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" : "something@something.com",
"created" : 1553243962038,
"invoices" : [ {
"invoiceId" : "A-1"
}, {
"invoiceId" : "A-2"
} ]
}
@Data
是lombok批注,用于生成获取器和设置器。
我尝试向Invoice类添加@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "invoiceId")
批注,但这不会更改输出。
请注意,我希望仅当将发票作为子级传递到容器模型时,才使用发票进行序列化。如果我想独立发送发票,它将在发票模型中序列化所有字段。我相信这是实施RESTful WS时的常见情况。
我需要为此编写客户序列化程序吗?
答案 0 :(得分:0)
您可以在@JsonAutoDetect
类上使用Invoice
来仅序列化invoiceId
字段,例如:
@JsonAutoDetect(
fieldVisibility = Visibility.NONE,
setterVisibility = Visibility.NONE,
getterVisibility = Visibility.NONE,
isGetterVisibility = Visibility.NONE,
creatorVisibility = Visibility.NONE
)
@Data
public class Invoice implements Serializable {
@JsonProperty (access = READ_ONLY)
private String invoiceId;
private List<Particular> particulars;
private Date invoiceDate;
}
这将确保只有invoiceId
穿过电线,并查看文档here。
更新
如果仅当将Invoice
作为嵌套对象发送时才具有此行为,则可以将其他字段设置为null
(或不首先设置这些字段)并使用{{ 1}}注释,例如:
@JsonInclude
答案 1 :(得分:0)
您可以使用@JsonIgnore
来忽略JSON响应中的属性。
或者您可以使用transient
关键字来避免序列化
答案 2 :(得分:0)
将以下bean视为对您的案例的略微修改:
@Data
@JsonFilter("idOnlyFilter")
@AllArgsConstructor
class Complex {
private String id;
private List<String> aList;
private Date aDate;
}
您可以使用@JsonFilter
概念在每个想要的bean上定义真正的粒度,序列化的条件是什么。特别注意idOnlyFilter
配置和ObjectMapper
批注中的过滤器名称 @JsonFilter
。
如下所示:
@Test
public void includeOnlyOneField() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
FilterProvider filters = new SimpleFilterProvider()
.addFilter("idOnlyFilter", SimpleBeanPropertyFilter.filterOutAllExcept("id"));
Complex complex = new Complex("a string", List.of(), new Date());
// when
String complexAsString = mapper.writer(filters).writeValueAsString(complex);
// then
assertThat(complexAsString).isEqualTo("{\"id\":\"a string\"}");
}
答案 3 :(得分:0)
我可以通过以下方式修改Customer类来实现这一目标。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div style=" width:256px; height:256px; margin:20px auto; ">
<svg id="artwork" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 256">
<style type="text/css">
@import url('https://fonts.googleapis.com/css?family=M+PLUS+1p');
text {
font-family: 'M PLUS 1p';
}
</style>
<a xlink:href="#">
<circle cx="57" cy="57" r="54.5" fill="#767dcc"/>
<text transform="translate(33.916 87)" font-size="90" font-family="M PLUS 1p">1</text>
</a>
</svg>
</div>
</body>
</html>
答案受https://stackoverflow.com/a/17583175/1365340
的启发这样,我可以生成带有发票ID列表的@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;
}
json。 Customer
对象在单独序列化时会从json中其所有字段中获取所有值。