Jackson Jr for casual JSON reading/writing from Java

Background

Learnt lessons

  • Mature, well-tested incremental/streaming decoder (“parser”) and encoder (“generator”)
  • High performance, low-overhead
  • Potential access to many other data formats (by latest count Jackson has dataformat modules for at least dozen formats from Avro to XML)

Approach

  1. Base the “mini Jackson” library on streaming API (`jackson-core`); this adds about 200kB of code for uber-jar, below lib itself
  2. Focus on simple databinding alternative, without mandatory tree model (but allow plugging of one with jackson-core `TreeCodec` / `TreeNode`, later on!)
  3. Keep API and jar size close to minimal (that is, a goal, not just wish)

Something old

  • Modular components like `jackson-jr-objects`, which depend on `jackson-core`
  • Uber-jar version `jackson-jr-all`, which shades in `jackson-core` (in different Java package) and includes all jackson-jr components

Something borrowed

  1. Properties inferred by existence of getters and setters (possibly requiring both; configurable), fields NOT used or supported
  2. Default no-argument constructor used (and required); except that single-String and single-int/long constructors are alternatively used for reading JSON String / JSON Number values
  3. No annotations used for configuration
String json = "{\"a\":[1,2,{\"b\":true},3],\"c\":3}";
Object ob = JSON.std.anyFrom(json); // will be `Map`
// or
Map<String,Object> map = JSON.std.mapFrom(json);
// or with bean that has properties 'a' and 'c':
MyBean bean = JSON.std.beanFrom(MyBean.class, INPUT);
String output = JSON.std.asString(map);
JSON.std.write(ob, new File("/tmp/stuff.json");
// and with indentation; but skip writing of null properties
byte[] bytes = JSON.std
.with(Feature.PRETTY_PRINT_OUTPUT)
.without(Feature.WRITE_NULL_PROPERTIES)
.asBytes(bean);

Something new

String json = JSON.std
.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
.composeString()
.startObject()
.put("a", 1)
.startArrayField("arr")
.add(1).add(2).add(3)
.end()
.startObjectField("ob")
.put("x", 3)
.put("y", 4)
.startArrayField("args").add("none").end()
.end()
.put("last", true)
.end()
.finish();
{
"a" : 1,
"arr" : [1,2,3],
"ob" : {
"x" : 3,
"y" : 4,
"args" : ["none"]
},
"last" : true
}

On configuration

  1. `WRITE_NULL_PROPERTIES`: whether `null` valued properties are written or not
  2. `WRITE_ENUMS_USING_INDEX`: are Enums written using index or String value (via `toString()`)?
  3. `PRETTY_PRINT_OUTPUT`: is output indented or not?
  4. `WRITE_DATES_AS_TIMESTAMP`: dates as `long` numbers or Strings?

Word on performance

Add-ons!

  1. `jr-stree`: simple JSON Tree implementation, exposing `TreeNode`s
  2. `jr-retrofit2`: jackson-jr plugin for version 2 of Square’s Retrofit library

--

--

--

Open Source developer, most known for Jackson data processor (nee “JSON library”), author of many, many other OSS libraries for Java, from ClassMate to Woodstox

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
@cowtowncoder

@cowtowncoder

Open Source developer, most known for Jackson data processor (nee “JSON library”), author of many, many other OSS libraries for Java, from ClassMate to Woodstox

More from Medium

import — Java Package Does Not Exist Error

Why Every Java Programmer should switch to Kotlin

Kotlin for Java Developers

SOLID principles in Java

Example