简体   繁体   English

杰克逊,序列化参考的一个属性

[英]Jackson, serialize one attribute of a reference

When serializing a Java object which has other object references, I need to serialize only one attribute of the nested object(usual case of foreign key, so serialize the "id" attribute of the object reference). 序列化具有其他对象引用的Java对象时,我只需要序列化嵌套对象的一个​​属性(通常是外键的情况,因此序列化对象引用的“id”属性)。 Ingore everything else. 其他一切。

For example, I have two classes which I need to serialize to JSON & XML(removed JPA annotations for clarity): 例如,我有两个类,我需要序列化为JSON和XML(为清楚起见,删除了JPA注释):

Relationship: User ->(one-to-many) AddressInformation; 关系:用户 - >(一对多)地址信息; Also: AddressInformation ->(one-to-one) User 另外: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

When serializing User for example, I need: 例如,在序列化用户时,我需要:

{
  "id" : "idofuser01",
  "email" : "some.email@gmail.com",
  "status" : "OK",
  "firstname" : "Filan",
  "lastname" : "Ovni",
  "defaultaddressid" : "idofaddress01",
}
enter code here

When serializing AddressInformation: 序列化AddressInformation时:

{
  "id" : "idofaddress01",
  "address" : "R.8. adn",
  "details" : "blah blah",
  "userid" : "idofuser01",
}

I have tried @JsonManageReference & @JsonBackReference with no success. 我试过@JsonManageReference@JsonBackReference没有成功。 As you can see I also tried @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") 如你所见,我也试过@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")

Just Found a way using Jackson 2.1+ . 刚刚找到了使用Jackson 2.1+的方法。

Annotate object references with(this will pick only the id attribute of AddressInformation ): 使用(这将仅选择AddressInformationid属性)注释对象引用:

@JsonProperty(value = "defaultaddressid")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityReference(alwaysAsId = true) 
public AddressInformation getDefaultAddress() {
    return defaultAddress;
}

Serialization works very well. 序列化工作得很好。

You can implement custom deserializer for this class and use it in User class. 您可以为此类实现自定义反序列化器,并在User类中使用它。 Example implementation: 示例实现:

class AddressInformationIdJsonSerializer extends JsonSerializer<AddressInformation> {
    @Override
    public void serialize(AddressInformation value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        jgen.writeString(value.getId());
    }
}

And configuration in User class: 并在User类中配置:

@JsonProperty(value = "defaultaddress")
@JsonSerialize(using = AddressInformationIdJsonSerializer.class)
public AddressInformation getDefaultAddress() {
    return defaultAddress;
}

### Generic solution for all classes which implement one interface ### ###实现一个接口的所有类的通用解决方案###
You can create interface which contains String getId() method: 您可以创建包含String getId()方法的接口:

interface Identifiable {
    String getId();
}

Serializer for this interface could look like that: 此接口的Serializer可能如下所示:

class IdentifiableJsonSerializer extends JsonSerializer<Identifiable> {
    @Override
    public void serialize(Identifiable value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        jgen.writeString(value.getId());
    }
}

And now, you can use this serializer for all Identifiable implementations. 现在,您可以将此序列化程序用于所有可Identifiable实现。 For example: 例如:

@JsonProperty(value = "defaultaddress")
@JsonSerialize(using = IdentifiableJsonSerializer.class)
public AddressInformation getDefaultAddress() {
    return defaultAddress;
}

of course: AddressInformation have to implement this interface: 当然: AddressInformation必须实现这个接口:

class AddressInformation implements Identifiable {
    ....
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM