Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson - serialize/deserialize property as JSON value

Tags:

java

json

jackson

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!

like image 679
jonc Avatar asked Aug 23 '12 16:08

jonc


1 Answers

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"}
like image 54
Integrating Stuff Avatar answered Nov 03 '22 01:11

Integrating Stuff