2. ● Assumes some familiarity with JAX-RS/DropWizard
● Jackson is the default DropWizard JSON provider
o … also on: RESTEasy, SpringMVC, Restlet, CXF
● Presentation mostly about data-binding
o reading JSON into Java Objects (POJOs)
o writing Java objects as JSON
● But Jackson offers more: Tree Model (JsonNode),
streaming read/write -- mix’n match!
● Not limited to JSON either (XML, CSV, ...)
Introduction
3. 1. Often “just works”, esp. with bit of practice
2. or with minor adjustments to
a. POJO structure/naming, and/or
b. JSON structure/naming
3. or by using annotations (regular, mix-in)
4. perhaps with changed Jackson defaults
5. using a datatype module (guava, joda)
6. or, using a more dynamic Java representation
a. Tree Model (JsonNode) or “untyped” (Maps of Lists)
7. Rarely if ever need custom handlers! (last resort)
Simple Usage: Claims
4. ● W/ default settings, Jackson reads JSON
a. No-argument constructor (any visibility)
b. Setter (“setValue(x)”) with any visibility (even
private), OR
c. public field of same name (“value”)
● W/ default settings, Jackson writes JSON
a. Public getter (“getValue()”), OR
b. public field of same name (“value”)
Simple Usage: Just Works
5. // traditional Bean
public class Point {
private int x, y;
public Point() { }
public int getX() {
return x;
}
public void setX(int x){
this.x = x;
}
// and same for ‘y’
}
Simple Usage: Just Works, 2
// or just:
public class Point {
public int x, y;
}
=>{ “x”:100, “y”:200 }
● recursively (nested POJOs)
● for all common JDK types
o Maps, Collections, arrays
o Date/Calendar
o binary (byte[]) as base64
6. ● Visibility rules, naming convention
configurable (default, per-class)
● Result of introspection, annotations is a
logical “Bean” type definition, with
a. “Creator” to use (default ctor, or creator)
b. Type, possibly polymorphic
c. Set of properties w/ accessors (getter/setter/field)
d. Filtering, type id/object id handler etc etc
Simple Usage: Just Works, 3
7. Sometimes default mapping not compatible:
● Naming not following bean style (C-style etc), or
individual properties “misnamed”
● Inadequate visibility (protected getters)
● No default constructor (can just add private one)
● Not all properties should be written in JSON
● All of above changeable via annotations too; but
sometimes simpler to just change class itself
Simple usage: Changing POJOs
8. ● While ‘ON’ stands for ‘Object Notation’:
o JSON structures that do NOT map nicely;
especially union types (“String or Array”)
o does NOT support basic Object properties:
Type metadata (no classes)
Object identity
o multiple ways to express types, object identity:
choice has big effect (Jackson supports many)
● Mapping means fitting _both_ sides
Simple usage: Changing JSON
9. ● @JsonProperty
o indicate inclusion, optionally different name
● @JsonIgnore
o indicate exclusion; either whole property, or just
accessor (if also @JsonProperty)
● @JsonPropertyOrder
o order of JSON properties has no semantics; but
sometimes nice to define output ordering
Simple usage: Annotations
10. ● @JsonCreator (for arg-taking constructor)
o delegating (“first bind as X, give to my
constructor”) or property-based
● @JsonValue for scalar types (most often)
Simple usage: Annotations
public class MyTimeType {
@JsonValue
public String asString() { … }
}
12. ● Simple idea: associate, don’t embed!
o no need to modify target class, or bytecode
● Define an interface, (abstract) class with annotations
● Associate source class with target:
o mapper.addMixInAnnotations(target, source);
● Same as if ‘target’ had annotations that ‘source’ has,
from Jackson perspective
See http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html
for more detailed description.
Simple usage: mix-in annotations
13. ● Visibility for introspection (hide/expose)
o mapper.setVisibility() (per accessor type)
o annotation: @JsonAutoDetect
o convenience vs. security
● Naming convention
o mapper.setPropertyNamingStrategy(x)
o annotation: @JsonNaming
o 3 standard implementations
(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_W
Simple usage: Jackson defaults
14. ● For reading JSON, DeserializationFeature
o ACCEPT_SINGLE_VALUE_AS_ARRAY
o FAIL_ON_UNKNOWN_PROPERTIES
o USE_BIG_DECIMAL_FOR_FLOATS
● For writing JSON, SerializationFeature
o FAIL_ON_EMPTY_BEANS
o INDENT_OUTPUT
o WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED
● mapper.enable(...) / disable(...)
Simple usage: Jackson defaults
15. But someone may already have solved your
problem!
Datatype modules exist for these and more:
● Guava
● Hibernate
● High-Performance Primitive Collection (HPPC)
● Joda
See: https://github.com/FasterXML/jackson
Simple usage: datatype modules
16. ● If structure (too)
dynamic, difficult to
match with POJO, or
o you just want a tiny
sliver, or you
o like JSON Pointer
● JsonNode similar to
XML DOM, ObjectNode
of json.org
Simple usage: go loose with Trees
JsonNode n = mapper.readTree(src);
String firstName = n
.path(“name”)
.path(“first”).asText();
// or with JSON Pointer:
String fn = n.at(“/name/first”)
.asText();
for (JsonNode child:
n.path(“children”)) {
int age = child.path(“age”).asInt
}
17. ● Not either or choice: can go back & forth:
Person person = mapper.treeToValue(root,
Person.class);
JsonNode childNode = mapper.valueToTree(
person.getChildren().get(0));
● Jackson can read/write JsonNodes just like POJOs;
even have JsonNode-valued properties.
Simple usage: Trees, 2
18. That’s All, Folks! Questions?
Visit Jackson home at
https://github.com/FasterXML/jackson
and/or join mailing lists at
https://groups.google.com/forum/#!forum/jack
son-user
Simple usage: in closing