Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Jackson Without Annotations Absolutely Require Setters?

Tags:

java

jackson

I'm using Jackson 1.6.4 and Java JDK 6.

I don't want to use Jackson annotations; I want to have immutable Java objects without setters.

The two requirements appear to conflict.

If I add private setters deserialization works fine.

I'm trying to not resort to private setters for my immutable objects - I'm stubborn that way.

I'm in the process of trying a custom implementation of VisibilityChecker to allow ANY field access.

But if anyone has some advice or lessons learned they can share I'd appreciate hearing them.

UPDATE: It's working.

Builder pattern, private constructor - a la Bloch "Effective Java".

It took setting deserialization configuration and visibility, but now it's good to go.

public class JsonMapper
{
   private static final int INITIAL_SIZE = 2048;
   /** See http://wiki.fasterxml.com/JacksonBestPracticeThreadSafety?highlight=(\bCategoryJackson\b) */
   private static ObjectMapper mapper;

   static
   {
      mapper = new ObjectMapper();

      mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
      SerializationConfig serializationConfig = mapper.getSerializationConfig();
      serializationConfig.setDateFormat(Person.DEFAULT_FORMATTER);

      mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,false);
      DeserializationConfig deserializationConfig = mapper.getDeserializationConfig();
      deserializationConfig.setDateFormat(Person.DEFAULT_FORMATTER);
      deserializationConfig.enable(DeserializationConfig.Feature.AUTO_DETECT_FIELDS);
      mapper.setVisibilityChecker(VisibilityChecker.Std.defaultInstance().withFieldVisibility(JsonAutoDetect.Visibility.ANY));
   }

   public static <T> String serialize(T o) throws IOException
   {
      StringWriter sw = new StringWriter(INITIAL_SIZE);
      mapper.writeValue(sw, o);

      return sw.toString();
   }

   public static <T> T deserialize(String source, Class<T> targetClass) throws IOException
   {
      ByteArrayInputStream stream = new ByteArrayInputStream(source.getBytes());
      TreeTraversingParser treeTraversingParser = new TreeTraversingParser(mapper.readTree(stream));
      treeTraversingParser.setCodec(mapper);

      return treeTraversingParser.readValueAs(targetClass);
   }
}
like image 357
duffymo Avatar asked Jan 27 '11 22:01

duffymo


People also ask

Does Jackson need setters?

Jackson can't deserialize into private fields with its default settings. Because it needs getter or setter methods.

Does Jackson use getters and setters?

Default jackon behaviour seems to use both properties (getters and setters) and fields to serialize and deserialize to json.

Is JsonProperty annotation necessary?

You definitely don't need all those @jsonProperty . Jackson mapper can be initialized to sereliazie/deserialize according to getters or private members, you of course need only the one you are using.

What is the use of Jackson annotations?

Jackson Annotations - @JacksonInject @JacksonInject is used when a property value is to be injected instead of being parsed from Json input. In the example below, we are inserting a value into object instead of parsing from the Json.


1 Answers

Glad to hear you made it work -- ability to change auto-detection visibility levels is a very powerful feature, but there are so many features that it is not trivial to find all there is.

Couple of additional pointers: if you do not want to add Jackson annotations in POJOs, you can still use mix-in annotations. With this, you can use @JsonCreator to specify non-default constructor to use which allows true immutable value types (more on Jackson and immutable types on this article).

And finally: while builder pattern is not yet directly supported, it has been planned as per this Jira entry.

like image 157
StaxMan Avatar answered Sep 20 '22 04:09

StaxMan