简体   繁体   中英

Jackson - serialize/deserialize property as JSON value

Using Jackson 2, I'm looking for a generic way to be serialize objects as a single value (then serialize them back later populating only that single field) without having to repetitively create a JsonSerializer / JsonDeserializer to handle each case. The @JsonIdentityInfo annotation comes pretty close but misses the mark a little bit since, as far as I can tell, it will always serialize the full child object on the first occurrence.

Here is an example of what I want to do. Given the classes:

class Customer {

    Long id = 99;
    String name = "Joe"; 
    // Lots more properties
}

class Order {
    String orderNum = "11111"
    @WhateverAnnotationsINeedHereToDoWhatIWant
    Customer customer;
}

I would like Order to serialize as either (either would be perfectly acceptable to me):

{"orderNum":"11111", "customer":"99"}
{"orderNum":"11111", "customer":{"id":99}}

What @JsonIdentityInfo does makes it more difficult to deal with on the client-side (we can assume that the client knows how to map the customer ID back into the full customer information).

@JsonIgnoreProperties could also come pretty close for the second JSON shown but would mean I would have to opt-out of everything but the one I want.

When I deserialize back I would just want the Customer to be initialzed with the "id" field only.

Any magic way to do this that I'm missing without getting into the soupy internals of Jackson? As far as I can tell, JsonDeserializer/JsonSerializer has no contextual information on the parent so there doesn't seem to be an easy way to create a @JsonValueFromProperty("id") type Jackson Mix-in then just look at that annotation in the custom Serializer/Deserializer.

Any ideas would be greatly appreciated. Thanks!

I once needed fine-grained control over the JSON returned per different type of request, and I am afraid I ended up using custom Serializers and Deserializers.

A simple alternative would be adding @JsonIgnore to the Customer field of Order and add the following getter to Order:

@JsonProperty("customer")
public Long getCustomerId(){
  if (customer != null){
    return customer.getId();
  }
  else {
    return null;
  }
}

The returned JSON would then be:

{"orderNum":"11111", "customer":"99"}

Another possibility could be use of @JsonValue , used on id field.

Jackson 2.1 will add a feature to force serialization of even the force reference as id (by new property, "firstAsId" for @JsonIdentityInfo ). That may not work well with deserialization for all cases but perhaps would work for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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