How can I get a Jackson mixin to work with private fields?

user949300 picture user949300 · Jun 7, 2012 · Viewed 9.1k times · Source

I was experimenting with Jackson 2.0 mixins to serialize a class with no annotations.

Simplified source code below. Note that I'm not using getters/setters, but it seemed like I should still be able to use mixins according to the documentation.

public class NoAnnotation {
   private Date created;
   private String name;

   // make one with some data in it for the test
   static NoAnnotation make() {
      NoAnnotation na= new NoAnnotation();
      na.created = new Date();
      na.name = "FooBear";
      return na;
   }

   // my Mixin "class"
   static class JacksonMixIn {
      JacksonMixIn(@JsonProperty("created") Date created,
                   @JsonProperty("name") String name)
         { /* do nothing */ }
   }

   // test code
   public static void main(String[] args) throws Exception {
      NoAnnotation na = NoAnnotation.make();
      ObjectMapper objectMapper = new ObjectMapper();
      objectMapper.addMixInAnnotations(NoAnnotation.class, JacksonMixIn.class);
      String jsonText = objectMapper.writeValueAsString(na);
      System.out.println(jsonText);
   }
}

When I run main I get

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class com.flyingspaniel.so.NoAnnotation and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.SerializationFeature.FAIL_ON_EMPTY_BEANS) )
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:51)
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:25)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:108)
    at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2407)
    at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:1983)
    at com.flyingspaniel.so.NoAnnotation.main(NoAnnotation.java:49)

When I follow the instructions in the Exception and add a line

objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

I no longer get an exception, but the result is an empty JSON object, {}.

If I make the fields public it works, but that is not something I want to do, as it's not a reasonable object design.

I'm guessing that I am leaving out a basic "setThis" step somewhere, but don't know what. How can I get mixins to work in this situation?

Answer

carlo.polisini picture carlo.polisini · Jun 8, 2012

If you want use the annotation mixin the correct way to declare it is:

static class JacksonMixIn {
    @JsonProperty Date created;
    @JsonProperty String name;
}

When done in this way you can control the fields to serialize simply including/excluding them from the mix in.