A brief tutorial on using Guava's Optional with Jackson JSON library

One serious limitation of using Jackson to deserialize the custom defined bean classe is that you cannot differentiate between a value missing in the input JSON or it is present but having null value. Consider the exampel below:

class MyBean {
  private String firstName;
  private String lastName;
  // Getters and setters here.
}

You cannot differentiate between the JSON inputs {"firstName": "John"} and {"firstName": "John", "lastName": null}. I.e. the lastName property being present in the input or not.

Guava library has an excellent tool to express missing values versus null values: Optional. Jackson supports integration with Guava library. The integration library can be accessed from jackson-datatype-guava package. To clearly express the null versus absent values, we can rewrite the bean class above as follows:

class MyBean {
  private Optional<String> firstName;
  private Optional<String> lastName;
  // Getters and setters here.
}

So before accessing the value, you will be just checking for its presence. I.e. myBean.getFirstName().isPresent().

If you don't care if the value is present or not, but just want to retrieve the value as null if absent, you can do myBean.fetFirstName().orNull().

BTW, if you are not making use of Guava libraries in your project, you are truly missing something great and makes you productive. Please give it a try.

Comments

Anonymous said…
Do you need to set the default value as absent? Or will jackson auto set it to absent if no value or null is provided?
Unknown said…
Setting default value makes sense, since although Jackson will set the value from JSON null, there is no concept of default values (with exception that if constructors are used with `@JsonCreator`, then nulls would actually be passed).
Anonymous said…
A bit confusing for someone new to Guava like myself, Jackson actually sets the property to null if the key is missing in the JSON and to Optional.absent() if it's present in the JSON, but with a null value. Useful nonetheless, thanks.
Anonymous said…
Absolutely confusing....

Why not set the bean property to Optional.absent() when the JSON field is absent? Then set the bean property to the value or null when the JSON property is present (thus, isPresent())?

Sure would make coding easier. For me, null is sent by REST client wanting to specifically null out the field. It's the same as sending a specific value, except it's null(aka. empty). If they don't have a field in the JSON, it's not because they want it nullified, but because it's not in *their* model and so not sent.

Meh. Easier enough to create my own deserializer, I supppose - just wish I didn't have to.

Popular posts from this blog

Gotchas with DBCP

A note on Java's Calendar set() method

The mysterious ORA-03111 error