While known for its first-class JSON handling for Java, Jackson is not limited to JSON: with no fewer than 9 supported data formats it can be used for reading and writing data in almost any data format. This talk offers introduction to reading and writing XML and CSV using Jackson.
2. Beyond JSON: Modules
● Modules extend Jackson functionality
o Most new features outside core
o Data type modules for supporting Joda, Guava & more
o JAX-RS provider for using Jackson in Jersey (et al)
o Data formats (this talk) for XML, CSV & more
o Other modules
Afterburner (code generation, +30% faster)
Mr Bean (generate impls of interfaces)
JSON Schema generator
JAXB Annotation support
3. Beyond JSON: data formats
Extensions to Jackson that
o implement Streaming API, to expose token/event
streams for reading, token-based writing
o sometimes augmented at data-binding (XML)
o some use ‘format schema’ helper objects (CSV, Avro,
Protobuf)
o allow full range of data-binding (read <X> into POJOs,
write POJOs as <X>)
4. Beyond JSON: data formats
● Existing data format modules
o Binary JSON: Smile, BSON, CBOR
o JSON-like: MessagePack, YAML
o Textual: CSV, XML
o Binary: Avro, Protobuf (soon!)
● Level of support for processing models
o All support data-binding
o Most support tree model (XML only partial)
o All expose streaming (XML partial)
5. non-JSON: from DropWizard
Two main ways to use from DropWizard:
● JAX-RS Provider (implement
MessageBodyReader/-Writer):
○ JSON, XML, Smile/CBOR (binary JSON)
○ Simply add a Maven dep (or jar), will auto-register
● DIY
○ InputStream for reading
○ StreamingOutput for writing
○ Can also use with JSON
6. From DropWizard: automatic
When auto-registering, simply annotate end
points with @Produces, @Consumes…
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_XML)
… and things will “Just Work”
7. From DropWizard: DIY
public class Resource {
private final static ObjectMapper mapper = new ObjectMapper();
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path(“/stuff”)
public StreamingOutput getStuff(InputStream input) throws IOException {
RequestObject req = mapper.readValue(input, RequestObject.class);
final ResponseObject response = …;
return new StreamingOutput() {
public void write(OutputStream out) throws IOException {
mapper.writeValue(out, response);
}
};
// although most commonly, would wrap in ‘Response’ object
}
}
8. From DropWizard: DIY
Things to note on DIY:
● More work but also more control over
configuration, error handling
● StreamingOutput
o Good for streaming large responses
o Usually wrapped in `Response` (to control headers,
response codes)
● InputStream:
o Need to invoke Bean Validation manually
9. XML from DropWizard
Jackson XML module, JAX-RS provider:
https://github.com/FasterXML/jackson-dataformat-xml
https://github.com/FasterXML/jackson-jaxrs-providers
and optional JAXB annotation support
https://github.com/FasterXML/jackson-module-jaxb-
annotations
10. XML from DropWizard
● Due to auto-registration, not much to add
● XML-specific annotations:
o element vs attribute (Jackson / JAXB annotations)
o wrapper vs unwrapped lists
● Jackson vs JAXB
o Both work, viable alternatives
o Jackson has more powerful POJO handling
o JAXB supports “XML-centric” approach
o Beware of XML-providers’ “JSON solutions”
11. Jackson XML, DIY
If you want to do XML outside of DropWizard:
public class Person {
@JacksonXmlProperty(isAttribute=true)
public int age;
public String name;
}
XmlMapper mapper = new XmlMapper();
String xml = mapper.writeValueAsString(new Person(...));
=> <Person age=”25”>
<name>Jason Jackson</name>
</Person>
12. CSV from DropWizard
Jackson CSV module:
https://github.com/FasterXML/jackson-dataformat-csv
No JAX-RS provider yet (need to figure out how to provide
schema); may be added in future.
13. CSV is Different
Main differences from other formats:
1. Shallow 2-dimensional (tabular) structure
2. Positional (column 1, 2, …)
3. Only native data type String
So how to map to Jackson’s model, POJOs?
1. Handle as “raw” content (List<String[]>)
2. Use schema objects to map position->name
14. CSV usage, “untyped”
Simple “untyped” usage:
CsvMapper mapper = new CsvMapper();
// or: new ObjectMapper(new CsvFactory());
// read into String[][], or Object[]:
String[][] rows = mapper.readValue(
"1,xyzn2,abcn", String[][].class);
// write similarly; one of:
String csv = mapper.writeValueAsString(rows);
mapper.writeValue(new File(“output.csv”), rows);
15. CSV usage, “untyped”
// or stream through, for large documents
MappingIterator<String[]> it = mapper
.reader(String[].class)
.readValues(csv);
while (it.hasNext()) {
String[] row = it.nextValue();
// do something with it
}
16. CSV usage, POJOs
But to get to POJOs, we need CsvSchema:
● simple mapping between column positions, names
o manually:
CsvSchema schema = CsvSchema.builder().addColumn("firstName")
.addColumn("lastName").build()
o or from input (first row) -- see next slide
o or from Java class:
CsvSchema schema = mapper.schemaFor(Pojo.class);
● also contains doc properties: linefeed, column separator...
● NOT formal “CSV Schema”
17. CSV usage, POJOs
Typically as simple as:
Value[] values = mapper.readerWithSchemaFor(Value.class)
.readValue(new File(“input.csv”), Value[].class);
// or with MappingIterator
mapper.writer(mapper.schemaFor(Value.class)
.writeValue(new File(“output.csv”, values);
// or using 1st line as header for mapping
CsvSchema sch = CsvSchema.emptySchema().withHeader();
values = mapper.reader(Value.class).with(schema)
.readValue(source);
18. CSV: variations
Many variations:
● some CSV documents define column names in first row
(enable/disable via CsvSchema object)
● Different column separator (“TSV” for tab-delimited),
line separator
● Optional quoting, and/or escaping
● Null value to output (can not omit -- default “”)
● Settings part of CsvSchema object
19. Beyond JSON, take-away
Key takeaway: one tool, usage as close to
baseline of JSON as possible.
Some follow-up ideas:
● dynamic enabling of binary JSON (HTTP
format negotation)
● YAML for configuration (DropWizard
already uses Jackson YAML)
20. Beyond JSON, the End
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/jackson-user