当序列化具有其他对象引用的Java对象时,我只需要序列化嵌套对象的一个属性(通常是外键的情况,因此序列化对象引用的“id”属性)。其他一切。
例如,我有两个类需要序列化为JSON& XML(为清楚起见,删除了JPA注释):
关系:用户 - >(一对多)地址信息; 另外:AddressInformation - >(一对一)用户
@XmlRootElement
public class User {
private String id;
private String firstName;
private String lastName;
private String email;
private AddressInformation defaultAddress;
private Set<AddressInformation> addressInformation;
public User() {
}
@JsonProperty(value = "id")
@XmlAttribute(name = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@JsonProperty(value = "firstname")
@XmlAttribute(name = "firstname")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@JsonProperty(value = "lastname")
@XmlAttribute(name = "lastname")
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@JsonProperty(value = "email")
@XmlAttribute(name = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@JsonIgnore
public Set<AddressInformation> getAddressInformation() {
return addressInformation;
}
public void setAddressInformation(Set<AddressInformation> addressInformation) {
this.addressInformation = addressInformation;
}
@JsonProperty(value = "defaultaddress")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public AddressInformation getDefaultAddress() {
return defaultAddress;
}
public void setDefaultAddress(AddressInformation defaultAddress) {
this.defaultAddress = defaultAddress;
}
}
AddressInformation:
@XmlRootElement
public class AddressInformation {
private String id;
private String address;
private String details;
private User user;
@JsonProperty(value = "id")
@XmlAttribute(name = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@JsonProperty(value = "details")
@XmlAttribute(name = "details")
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
@JsonProperty(value = "address")
@XmlAttribute(name = "address")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public AddressInformation() {
super();
}
}
enter code here
例如,在序列化用户时,我需要:
{
"id" : "idofuser01",
"email" : "some.email@gmail.com",
"status" : "OK",
"firstname" : "Filan",
"lastname" : "Ovni",
"defaultaddressid" : "idofaddress01",
}
enter code here
序列化AddressInformation时:
{
"id" : "idofaddress01",
"address" : "R.8. adn",
"details" : "blah blah",
"userid" : "idofuser01",
}
我试过@JsonManageReference
&amp; @JsonBackReference
没有成功。如您所见,我也尝试了@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
答案 0 :(得分:13)
使用Jackson 2.1+找到了一种方法。
使用(仅选择id
的{{1}}属性)注释对象引用:
AddressInformation
序列化效果很好。
答案 1 :(得分:3)
您可以为此类实现自定义反序列化器,并在User
类中使用它。示例实现:
class AddressInformationIdJsonSerializer extends JsonSerializer<AddressInformation> {
@Override
public void serialize(AddressInformation value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeString(value.getId());
}
}
User
类中的配置:
@JsonProperty(value = "defaultaddress")
@JsonSerialize(using = AddressInformationIdJsonSerializer.class)
public AddressInformation getDefaultAddress() {
return defaultAddress;
}
###实现一个界面的所有类的通用解决方案###
您可以创建包含String getId()
方法的接口:
interface Identifiable {
String getId();
}
此界面的序列化程序可能如下所示:
class IdentifiableJsonSerializer extends JsonSerializer<Identifiable> {
@Override
public void serialize(Identifiable value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeString(value.getId());
}
}
现在,您可以将此序列化程序用于所有Identifiable
实现。例如:
@JsonProperty(value = "defaultaddress")
@JsonSerialize(using = IdentifiableJsonSerializer.class)
public AddressInformation getDefaultAddress() {
return defaultAddress;
}
当然:AddressInformation
必须实现此接口:
class AddressInformation implements Identifiable {
....
}