Rbi-u-b
Rbi-u-b

Reputation: 58

Dynamic serialization/deserialization

I use Spring MVC and Jackson to drive the API of a application that I work in. I am faced with the following situation, we need serialize the Person class below in two different ways...

@Entity
Order{
    String id;
    String name;
    String address;
    List<Items> items;
}

@Entity
Item{
    String id;
    String description:
}

The two situations reposes on the serialization or not of the content of the "items" field in accord with the service that was called.

For example, the service http://localhost/order, results without the "items" field.

{
 "id": "1", 
 "name" : "Bill",
 "address" : "any address",
}

In the other hands, the second way is http://localhost/order/[id_order]/item/[ids_items], results with the field "items" that was give on the parameter.

{
 "id": "1", 
 "name" : "Bil",
 "address" : "any",
 "items" : [{
          "id" : "33",
          "description" : "Item 33"
      }]
}

Upvotes: 3

Views: 1886

Answers (2)

cassiomolin
cassiomolin

Reputation: 131187

@JsonView

You can use @JsonView to filter fields depending on the context of serialization. It is supported by Spring MVC.

First define your views:

public class View {         
    interface Default { }  
    interface Detailed extends Default { }   
}

Then annotate your fields using the desired view:

@Entity
public class Order {

    @JsonView(View.Default.class)
    private String id;

    @JsonView(View.Default.class)
    private String name;

    @JsonView(View.Default.class)
    private String address;

    @JsonView(View.Detailed.class)
    private List<Items> items;

    // Getters and setters
}

Finally annotate your controller methods to use a view when serializing the response:

@JsonView(View.Default.class) 
@RequestMapping(value = "/order", method = RequestMethod.GET)  
public ResponseEntity<Order> getOrder() {
    ... 
}

@JsonView(View.Detailed.class)
@RequestMapping(value = "/order-with-items", method = RequestMethod.GET)  
public ResponseEntity<SampleResults> getOrderWithItems() {
    ... 
}

In order to make it work, you may need to disable the default view inclusion in your ObjectMapper:

mapper.disable(MapperFeature.DEFAULT_VIEW_INCLUSION);

Upvotes: 3

Ervin Szilagyi
Ervin Szilagyi

Reputation: 16815

With jackson you can modify the result json string on the fly. For example:

    // create a new order
    Order order = new Order("id", "name", "addr");
    ObjectMapper mapper = new ObjectMapper();

    // create a json string with the order
    JsonNode node = mapper.valueToTree(order);
    //the content of the node at this moment is:
    //{"id":"id","name":"name","address":"addr"}

    // create an ArrayList with the Items
    ArrayList<Item> items = new ArrayList<Item>();
    items.add(new Item("id1", "desc1"));
    items.add(new Item("id2", "desc2"));

    // transform the ArrayList to a json string and add it 
    // the the previous node with the Order
    ((ObjectNode)node).put("items", mapper.valueToTree(items));
    String jsonString = node.toString();
    System.out.println(jsonString);

The final output is:

{"id":"id","name":"name","address":"addr","items":[{"id":"id1","description":"desc1"},{"id":"id2","description":"desc2"}]}

For more information visit the official documentation page: https://github.com/FasterXML/jackson-databind/

Upvotes: 0

Related Questions