Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson custom serialization under Spring 3 MVC

I have a couple of POJOs which looks like this:

class Items {
    List<Item> items;

    public List<Item> getItems() {
        return items;
    }

    ...
}

class Item {
    String name;
    Date insertionDate;

    ...
}

I want to be able to serialize the Date field in Item using a custom format (add a prefix to the date, something like "Date:xxx"), but I don't want to do that always (as it's used by other consumers which don't require this prefix), only in specific cases.

If I annotate Item's getInsertionDate() with@JsonSerialize(using = CustomDateSerializer.class) I can probably make this work, however, I don't want to do that since I don't always want to serialize this field using this method, only in a specific case.

So ideally, I would do this in my controller which does want to customize the serialization:

@JsonSerialize(using = CustomDateSerializer.class)
public List<Item> getItems() {
   ....
}

where CustomDateSerializer extends SerializerBase<Date> and Jackson would figure out that it should serialize each item in the List using the default serializer, and when it hits a Date object it should use my custom serializer. Of course this does not work since that's not how @JsonSerialize is used, but is there a way to make this work other than to wrap Item with a wrapper and use that wrapper when I want the custom serialization? Am I thinking about this the wrong way and there's another way to do this?

Note that I'm using Spring MVC so I'm not calling the serialization directly.

Any help would be much appreciated :)

like image 982
TheZuck Avatar asked Jan 01 '13 20:01

TheZuck


1 Answers

The problem is that Jackson does not see the annotations on getItems() if it is a service end point method; it is typically only passed type List<Item> that Spring determines. With JAX-RS (like Jersey), annotations associated with that method are passed, however (and perhaps Spring has some way as well); although it then requires bit more support from integration code (for JAX-RS, Jackson JAX-RS JSON provider module) to pass that along.

It might be easier to actually create a separate POJO (and not pass List types) so that you can add necessary annotations.

If you were using Jackson directly, you could also use ObjectWriter and specify default date format to use. But I don't know if Spring allows you to do that (most frameworks do not and only expose configurability of ObjectMapper).

One more note -- instead of custom serializer (and/or deserializer), you can also use simple annotations with Dates (and on Jackson 2.x):

public class DateStuff {
  @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="'Date:'yyyy'-'MM'-'dd")
  public Date date;
}

to specify per-property format override.

like image 117
StaxMan Avatar answered Nov 14 '22 09:11

StaxMan