Rick

Rick
Rick

Sunday, January 5, 2014

Boon JSON in five minutes, Faster Java JSON parsing, and serialization!



Boon and JSON

Boon is not a JSON parsing project. It is more than that, but JSON parsing is intrinsic to what Boon is all about. Boon is the fastest way to serialize and parse JSON in Java so far. It is faster at object serialization, enabling JSON expressions, JSON parsing and much more. Boon JSON is FAST! In addition it has a very easy to use, convention-based API.
Fastest JSON Parser aroundFastest JSON Parser in the west!
Latest round of benchmarks to coincide with release (older now)

Update: The new Groovy JSON parser based on Boon JSON parser is 20x faster than the previous Groovy JSON parser circa Groovy 2.2! Groovy JSON support and the Boon JSON parser are up to 3x to 5x faster than Jackson at parsing JSON from String and char[], and 2x to 4x faster at parsing byte[]. Groovy now has the fastest JSON parser on the JVM. 


Updated Benchmark from April 2014



TOC

Processing model: Data Binding

Boon mainly focuses on data binding and index overlay. The final interface is always about data binding as it is the most convenient one to use. It gets this idea from Jackson. Boon data binding allows for conversion between JSON data and Java objects.
There is no public tree model in Boon JSON or streaming model. The end users view is always a data binding view.
The ObjectMapper enables data binding and is built on top of the Boon JsonParser and JsonSerializer APIs, and mimics the Jackson API, which is the most popular Java JSON serializer/parser.
You can do simple data binding that only uses standard JDK container types (List, Maps) and scalar types (String, Boolean, Number, nulls). There is even a low-level API that can do wrapper-less (no auto-boxing) primitive arrays. You can also do full data binding that can use full range of Java types including "POJOs" (Plain Old Java Objects) such as Java Beans. Both can be used via the all-powerful ObjectMapper interface. The learning curve from Jackson should be minimal, and the speed-up can be up to 5x.

Serialization

Serialization is achieved by:
      ObjectMapper mapper =  ObjectMapperFactory.create();
      mapper.writeValue(dst, myBean); // where 'dst' can be File, OutputStream or Writer

Full Data Binding

When using full data binding, deserialization type must be fully specified as something other than Object.class. For example:
MyBean value = mapper.readValue(src, MyBean.class); // 'src' can be File, InputStream, Reader, String
The main complication is handling of Generic types: if they are used, one has to use the two argument version of readValue to work around Java Type Erasure:
List<MyBean> beans = mapper.readValue(src, List.class, MyBean.class);

"Simple" Data Binding

As mentioned above, simple here just means that range of value types is limited to core JDK types. If this is acceptable, deserialization type can be simply defined as Object.class. This can apply at root level (for calls to ObjectMapper, as well as at lower level -- whatever value are declared to be of basic Object type will use Simple data binding. Simple like this:
      Object root = mapper.readValue(src, Object.class);
      Map<String,Object> rootAsMap =  mapper.readValue(src, Map.class);

Complete code listing for tutorial so far

package org.boon.json;

import org.boon.Lists;

import java.io.File;
import java.util.List;
import java.util.Map;

import static org.boon.Boon.puts;

/**
 * Created by rick on 1/4/14.
 */
public class JsonTutorial {


    public static class MyBean {
        String name = "Rick";

        @Override
        public String toString() {
            return "MyBean{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }

    public static void main (String... args) throws Exception {

        MyBean myBean = new MyBean();
        File dst = File.createTempFile("emp", ".json");

        ObjectMapper mapper =  ObjectMapperFactory.create();

        puts ("json string", mapper.writeValueAsString( myBean ));

        mapper.writeValue( dst, myBean ); // where 'dst' can be File, OutputStream or Writer


        File src = dst;
        MyBean value = mapper.readValue(src, MyBean.class); // 'src' can be File, InputStream, Reader, String



        //MyBean value = mapper.readValue(src, MyBean.class); // 'src' can be File, InputStream, Reader, String

        puts ("mybean", value);



        Object root = mapper.readValue(src, Object.class);
        Map<String,Object> rootAsMap =  mapper.readValue(src, Map.class);

        puts ("root", root);
        puts ("rootAsMap", rootAsMap);



        MyBean myBean1 = new MyBean(); myBean1.name = "Diana";
        MyBean myBean2 = new MyBean(); myBean2.name = "Rick";

        dst = File.createTempFile("empList", ".json");

        final List<MyBean> list = Lists.list( myBean1, myBean2 );

        puts ("json string", mapper.writeValueAsString( list ));

        mapper.writeValue( dst, list );

        src = dst;

        List<MyBean> beans = mapper.readValue(src, List.class, MyBean.class);

        puts ("mybeans", beans);





    }
}
Output from the above listing:
json string {"name":"Rick"} 
mybean MyBean{name='Rick'} 
root {name=Rick} 
rootAsMap {name=Rick} 
json string [{"name":"Diana"},{"name":"Rick"}] 
mybeans [MyBean{name='Diana'}, MyBean{name='Rick'}] 

Examples of it "just works"

Full Data Binding (POJO) Example
Boon's ObjectMapper "just works" for mapping JSON data into plain old Java objects ("POJOs"). For example, given JSON data:
{
    "gender": "MALE",
    "name": {
        "first": "Richard",
        "last": "Hightower"
    },
    "verified": true
}
To create the above JSON file, you could serialize this Java POJO:
  public class User {
      public enum Gender { MALE, FEMALE };

      public static class Name {
          private String first, last;

          public Name( String _first, String _last ) {
              this.first = _first;
              this.last = _last;
          }

          public String getFirst() { return first; }
          public String getLast() { return last; }

          public void setFirst(String s) { first = s; }
          public void setLast(String s) { last = s; }
      }

      private Gender gender;
      private Name name;
      private boolean isVerified;

      public Name getName() { return name; }
      public boolean isVerified() { return isVerified; }
      public Gender getGender() { return gender; }

      public void setName(Name n) { name = n; }
      public void setVerified(boolean b) { isVerified = b; }
      public void setGender(Gender g) { gender = g; }
  }
To produce the above JSON, you can create a serialize User as follows:
      ObjectMapper mapper =  ObjectMapperFactory.create();

      User user = new User();
      user.setGender( User.Gender.MALE );
      user.setName(new User.Name("Richard", "Hightower"));
      user.setVerified( true );

      puts ( mapper.writeValueAsString( user ) );
This JSON gets produced:
{
    "gender": "MALE",
    "name": {
        "first": "Richard",
        "last": "Hightower"
    },
    "verified": true
}
It is just as easy to read and write files:
Now to write/serialize and then read/deserialize this user to/fro to a file.
Write to a file:
      File file = File.createTempFile( "user", ".json" );

      mapper.writeValue( file, user );
Read from a file
      User userFromFile = mapper.readValue( file, User.class );

      puts ( userFromFile );
The puts method is like System.out.println of sorts and is part of Boon.

Using Streams, Readers, Writers, etc.

Boon also works with Streams, Readers, Writers, etc.
Read from a inputStream using JDK 1.7 Files utility:
      Path path = Paths.get(file.toString());
      InputStream inputStream = Files.newInputStream(path);

      User userFromInput = mapper.readValue( inputStream, User.class );
      puts ( "userFromInput", userFromInput );
Read from a reader using JDK 1.7 Files utility:
      Reader reader = Files.newBufferedReader( path, StandardCharsets.UTF_8 );
      User userFromReader = mapper.readValue( reader, User.class );
      puts ( "userFromReader", userFromReader );

Boon and REST

Boon ships with an IO library that makes it easy to read/write from URLs, and other file systems:
      User userFromURL = mapper.readValue( IO.read("http://fromsomewebsite/user.json"), User.class );
      puts ( "userFromURL", userFromURL );
Boon also makes making JSON calls to REST web services easy as you can use Boon's HTTP utilities as follows:
       String results = HTTP.postJSON("http://foo.com/bar/add/user", mapper.writeValueAsString( user ) );
       AddUserResponse response = mapper.readValue( results, AddUserResponse.class );
Here is an example of getting a listing of users from a REST call:
       List <User> userList = mapper.readValue( HTTP.getJSON("http://foo.com/bar/user/listing"), 
                                          List.class, User.class );

Complete code listing so far for tutorial

package org.boon.json;

import org.boon.Lists;
import org.boon.core.Dates;

import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static org.boon.Boon.puts;

/**
 * Created by rick on 1/4/14.
 */
public class JsonTutorial {


    public static class MyBean {
        String name = "Rick";

        @Override
        public String toString() {
            return "MyBean{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }


    public static class User {
        public enum Gender { MALE, FEMALE };

        public static class Name {
            private String first, last;

            public Name( String _first, String _last ) {
                this.first = _first;
                this.last = _last;
            }

            public String getFirst() { return first; }
            public String getLast() { return last; }

            public void setFirst(String s) { first = s; }
            public void setLast(String s) { last = s; }

            @Override
            public String toString() {
                return "Name{" +
                        "first='" + first + '\'' +
                        ", last='" + last + '\'' +
                        '}';
            }
        }

        private Gender gender;
        private Name name;
        private boolean verified;
        private Date birthDate;

        public Name getName() { return name; }
        public boolean isVerified() { return verified; }
        public Gender getGender() { return gender; }

        public void setName(Name n) { name = n; }
        public void setVerified(boolean b) { verified = b; }
        public void setGender(Gender g) { gender = g; }

        public Date getBirthDate() { return birthDate; }
        public void setBirthDate( Date birthDate ) { this.birthDate = birthDate; }

        @Override
        public String toString() {
            return "User{" +
                    "gender=" + gender +
                    ", name=" + name +
                    ", isVerified=" + verified +
                    '}';
        }
    }


    public static void part1 () throws Exception {


        MyBean myBean = new MyBean();
        File dst = File.createTempFile("emp", ".json");

        ObjectMapper mapper =  ObjectMapperFactory.create();

        puts ("json string", mapper.writeValueAsString( myBean ));

        mapper.writeValue( dst, myBean ); // where 'dst' can be File, OutputStream or Writer


        File src = dst;
        MyBean value = mapper.readValue(src, MyBean.class); // 'src' can be File, InputStream, Reader, String

        puts ("mybean", value);



        Object root = mapper.readValue(src, Object.class);
        Map<String,Object> rootAsMap =  mapper.readValue(src, Map.class);

        puts ("root", root);
        puts ("rootAsMap", rootAsMap);



        MyBean myBean1 = new MyBean(); myBean1.name = "Diana";
        MyBean myBean2 = new MyBean(); myBean2.name = "Rick";

        dst = File.createTempFile("empList", ".json");

        final List<MyBean> list = Lists.list( myBean1, myBean2 );

        puts ("json string", mapper.writeValueAsString( list ));

        mapper.writeValue( dst, list );

        src = dst;

        List<MyBean> beans = mapper.readValue(src, List.class, MyBean.class);

        puts ("mybeans", beans);


    }

    public static void part2 () throws Exception {

        ObjectMapper mapper =  ObjectMapperFactory.create();

        User user = new User();
        user.setGender( User.Gender.MALE );
        user.setName(new User.Name("Richard", "Hightower"));
        user.setVerified( true );
        user.setBirthDate( Dates.getUSDate( 5, 25, 1980 ) );


        puts (mapper.writeValueAsString( user ));



        //Now to write and then read this as a file.

        File file = File.createTempFile( "user", ".json" );

        mapper.writeValue( file, user );

        User userFromFile = mapper.readValue( file, User.class );

        puts ( "userFromFile", userFromFile );


        Path path = Paths.get(file.toString());
        InputStream inputStream = Files.newInputStream(path);

        User userFromInput = mapper.readValue( inputStream, User.class );
        puts ( "userFromInput", userFromInput );


        Reader reader = Files.newBufferedReader( path, StandardCharsets.UTF_8 );
        User userFromReader = mapper.readValue( reader, User.class );

        puts ( "userFromReader", userFromReader );


    }

    public static void main (String... args) throws Exception {

        part1();
        part2();

    }
}

Working with dates

Going back to our user example. By default if you print out a date, it looks like this:
      ObjectMapper mapper =  ObjectMapperFactory.create();
      puts ( mapper.writeValueAsString( user ) );
The above generates this:
{
    "gender": "MALE",
    "name": {
        "first": "Richard",
        "last": "Hightower"
    },
    "verified": true,
    "birthDate": 328147200766
}

...
//user was initialized as follows:
    static User user = new User();
    static {
        user.setGender( User.Gender.MALE );
        user.setName(new User.Name("Richard", "Hightower"));
        user.setVerified( true );
        user.setBirthDate( Dates.getUSDate( 5, 25, 1980 ) );
    }
The issue is 328147200766 is not very friendly way to write a date. One of the nice things about JSON is it is readable, and that date is not very readable. JavaScript formats a date using a standard format, and if you are working with JavaScript, it can easily parse this standard format if you enable it.
Since this date format is the de facto standard, Boon makes it easy to use this format as follows:
      ObjectMapper mapper =  ObjectMapperFactory.create();
      puts ( mapper.writeValueAsString( user ) );
Generates this user with a human readable date.
{
    "gender": "MALE",
    "name": {
        "first": "Richard",
        "last": "Hightower"
    },
    "verified": true,
    "birthDate": "1980-05-26T00:00:00.014Z"
}
The date gets converted into GMT and then converted into a human readable string.
You can customize how Strings, Dates, Arrays, Collections, etc. are output quite easily, but that is beyond the scope of the five minute guide.
Boon can read and write this date format on the fly, and this is the date format that JavaScript browser use to convey dates.
Example of reading LONG date format on the fly to/for:
      ObjectMapper mapper =  ObjectMapperFactory.create();
      puts ( mapper.writeValueAsString( user ) );

      User user2 = mapper.readValue( mapper.writeValueAsString( user ), User.class );

      puts (user2);
Example of reading JSON string date format on the fly to/for:
      ObjectMapper mapper =  ObjectMapperFactory.createUseJSONDates();
      puts ( mapper.writeValueAsString( user ) );

      User user2 = mapper.readValue( mapper.writeValueAsString( user ), User.class );

      puts (user2);
Output:
{"gender":"MALE","name":{"first":"Richard","last":"Hightower"},"verified":true,"birthDate":328147200193} 
User{gender=MALE, name=Name{first='Richard', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980} 

{"gender":"MALE","name":{"first":"Richard","last":"Hightower"},"verified":true,"birthDate":"1980-05-26T00:00:00.193Z"} 
User{gender=MALE, name=Name{first='Richard', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980} 
Notice that the long and the JSON style date are written and read with ease.

"Raw" Data Binding Example

In cases where you do not have (and don't want to create) specific Java classes to bind JSON to/from, "Untyped data binding" may be a better approach. It is used same way as full data binding, except that the formal binding type is specified simply as Object.class (or Map.class, List.class, String[].class, int[].class, etc. if more specific typing is wanted). The earlier binding of JSON that represent User data could have been done by:
Map userData = mapper.readValue(new File("user.json"), Map.class); and userData would be like one we would explicit construct by:
      ObjectMapper mapper = ObjectMapperFactory.createUseJSONDates();


      puts( mapper.writeValueAsString( user ) );


      //Now to write and then read this as a file.

      File file = File.createTempFile( "user", ".json" );

      mapper.writeValue( file, user );

      //Reading the value as Object returns a list of map, and in this case a map.
      Object userFromFile = mapper.readValue( file, Object.class );

      puts( "userFromFile", "type", userFromFile.getClass(), "value", userFromFile );

      //Here we can read it as a map.
      Map<String, Object> map = (Map<String, Object>) mapper.readValue( file, Map.class );

      
      puts( "userFromFile", "type", map.getClass(), "value", map );


      //We can access this individual properties with the map interface
      puts( "userFromFile.name", "type", map.get("name").getClass(),
              "value", map.get("name") );

      //We can even get to the birthdate, notice birthdate gets converted to a date because
      //boon recognizes the date format string
      puts( "userFromFile.birthDate", "type", map.get("birthDate").getClass(),
              "value", map.get("birthDate") );


      //Gender gets read in as a string since we did not have an class to let us know it was an enum
      puts( "userFromFile.gender", "type", map.get("gender").getClass(),
              "value", map.get("gender") );

     //Since this is boon, we can always convert the map into a field later.
     User userFromMap =
             MapObjectConversion.fromMap(
                     map, User.class);

      puts ( userFromMap );
Output
{"gender":"MALE","name":{"first":"Richard","last":"Hightower"},"verified":true,"birthDate":"1980-05-26T00:00:00.826Z"} 
userFromFile type class org.boon.core.value.LazyValueMap value {gender=MALE, birthDate=Sun May 25 17:00:00 PDT 1980, verified=true, name={last=Hightower, first=Richard}} 
userFromFile type class org.boon.core.value.LazyValueMap value {gender=MALE, birthDate=Sun May 25 17:00:00 PDT 1980, verified=true, name={last=Hightower, first=Richard}} 
userFromFile.name type class org.boon.core.value.LazyValueMap value {last=Hightower, first=Richard} 
userFromFile.birthDate type class java.util.Date value Sun May 25 17:00:00 PDT 1980 
userFromFile.gender type class java.lang.String value MALE 
User{gender=MALE, name=Name{first='Richard', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980} 
The class LazyValueMap implements java.util.Map. The boon utility class MapObjectConversion can read to/fro maps just likeObjectMapper can read to/fro JSON.
This obviously works both ways: if you did construct such a Map (or bind from JSON and modify), you could write out just as before, by:
  mapper.writeValue(new File("user-modified.json"), userMap);
How does this work? By specifying Map.class, we do not specify generic key/value types. But ObjectMapper does know how to bind JSON data to and from Maps (and Lists, arrays, wrapper types, primitives, primitive arrays), and does just that. Fundamentally JSON data has no "real" type as far as Boon is concerned -- if it can be properly mapped to a type you give, it will be mapped.

Data Binding with Generics

In addition to binding to POJOs and "simple" types, there is one additional variant: that of binding to generic (typed) containers. This case requires special handling due to so-called Type Erasure (used by Java to implement generics in somewhat backwards compatible way), which prevents you from using something like Collection.class (which does not compile).
So if you want to bind data into a List you will need to use:
Working with generics
      mapper.writeValue( file, users  );
      List<User> userList = mapper.readValue( file, List.class, User.class  );
      puts (userList);
Output
[
    {
        "gender": "FEMALE",
        "name": {
            "first": "Diana",
            "last": "Hightower"
        },
        "verified": true,
        "birthDate": "1984-08-22T00:00:00.002Z"
    },
    {
        "gender": "MALE",
        "name": {
            "first": "Rick",
            "last": "Hightower"
        },
        "verified": true,
        "birthDate": "1980-05-26T00:00:00.941Z"
    }
]
Full listing so far:
package org.boon.json;

import org.boon.Lists;
import org.boon.core.Dates;
import org.boon.core.reflection.BeanUtils;
import org.boon.core.reflection.MapObjectConversion;

import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static org.boon.Boon.puts;

/**
 * Created by rick on 1/4/14.
 */
public class JsonTutorial {


    public static class MyBean {
        String name = "Rick";

        @Override
        public String toString() {
            return "MyBean{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }


    public static class User {
        public enum Gender {MALE, FEMALE}

        ;

        public static class Name {
            private String first, last;

            public Name( String _first, String _last ) {
                this.first = _first;
                this.last = _last;
            }

            public String getFirst() {
                return first;
            }

            public String getLast() {
                return last;
            }

            public void setFirst( String s ) {
                first = s;
            }

            public void setLast( String s ) {
                last = s;
            }

            @Override
            public String toString() {
                return "Name{" +
                        "first='" + first + '\'' +
                        ", last='" + last + '\'' +
                        '}';
            }
        }

        private Gender gender;
        private Name name;
        private boolean verified;
        private Date birthDate;

        public Name getName() {
            return name;
        }

        public boolean isVerified() {
            return verified;
        }

        public Gender getGender() {
            return gender;
        }

        public void setName( Name n ) {
            name = n;
        }

        public void setVerified( boolean b ) {
            verified = b;
        }

        public void setGender( Gender g ) {
            gender = g;
        }

        public Date getBirthDate() {
            return birthDate;
        }

        public void setBirthDate( Date birthDate ) {
            this.birthDate = birthDate;
        }

        @Override
        public String toString() {
            return "User{" +
                    "gender=" + gender +
                    ", name=" + name +
                    ", verified=" + verified +
                    ", birthDate=" + birthDate +
                    '}';
        }
    }


    static User user = new User();

    static {
        user.setGender( User.Gender.MALE );
        user.setName( new User.Name( "Richard", "Hightower" ) );
        user.setVerified( true );
        user.setBirthDate( Dates.getUSDate( 5, 25, 1980 ) );
    }

    public static void part1() throws Exception {


        MyBean myBean = new MyBean();
        File dst = File.createTempFile( "emp", ".json" );

        ObjectMapper mapper = ObjectMapperFactory.create();

        puts( "json string", mapper.writeValueAsString( myBean ) );

        mapper.writeValue( dst, myBean ); // where 'dst' can be File, OutputStream or Writer


        File src = dst;
        MyBean value = mapper.readValue( src, MyBean.class ); // 'src' can be File, InputStream, Reader, String

        puts( "mybean", value );


        Object root = mapper.readValue( src, Object.class );
        Map<String, Object> rootAsMap = mapper.readValue( src, Map.class );

        puts( "root", root );
        puts( "rootAsMap", rootAsMap );


        MyBean myBean1 = new MyBean();
        myBean1.name = "Diana";
        MyBean myBean2 = new MyBean();
        myBean2.name = "Rick";

        dst = File.createTempFile( "empList", ".json" );

        final List<MyBean> list = Lists.list( myBean1, myBean2 );

        puts( "json string", mapper.writeValueAsString( list ) );

        mapper.writeValue( dst, list );

        src = dst;

        List<MyBean> beans = mapper.readValue( src, List.class, MyBean.class );

        puts( "mybeans", beans );


    }

    public static void part2() throws Exception {

        ObjectMapper mapper = ObjectMapperFactory.create();


        puts( mapper.writeValueAsString( user ) );


        //Now to write and then read this as a file.

        File file = File.createTempFile( "user", ".json" );

        mapper.writeValue( file, user );

        User userFromFile = mapper.readValue( file, User.class );

        puts( "userFromFile", userFromFile );


        Path path = Paths.get( file.toString() );
        InputStream inputStream = Files.newInputStream( path );

        User userFromInput = mapper.readValue( inputStream, User.class );
        puts( "userFromInput", userFromInput );


        Reader reader = Files.newBufferedReader( path, StandardCharsets.UTF_8 );
        User userFromReader = mapper.readValue( reader, User.class );

        puts( "userFromReader", userFromReader );


    }

    public static void part3() throws Exception {
        part3_1();
        part3_2();
    }

    public static void part3_1() throws Exception {

        ObjectMapper mapper = ObjectMapperFactory.create();
        puts( mapper.writeValueAsString( user ) );

        User user2 = mapper.readValue( mapper.writeValueAsString( user ), User.class );

        puts( user2 );
    }


    public static void part3_2() throws Exception {

        ObjectMapper mapper = ObjectMapperFactory.createUseJSONDates();
        puts( mapper.writeValueAsString( user ) );

        User user2 = mapper.readValue( mapper.writeValueAsString( user ), User.class );

        puts( user2 );

    }

    public static void part5() throws Exception {

        puts ("\n\n\n", "\npart5");

        ObjectMapper mapper = ObjectMapperFactory.createUseJSONDates();


        final User diana = BeanUtils.copy( user );
        final User rick = BeanUtils.copy( user );
        diana.getName().setFirst( "Diana" );
        rick.getName().setFirst( "Rick" );
        diana.setBirthDate( Dates.getUSDate( 8, 21, 1984 ) );


        File file = File.createTempFile( "userList", ".json" );

        List<User> users = Lists.list( diana, rick );

        mapper.writeValue( file, users  );


        List<User> userList = mapper.readValue( file, List.class, User.class  );


        puts (userList);

        puts ( mapper.writeValueAsString( userList ) );


    }

    public static void part4() throws Exception {

        ObjectMapper mapper = ObjectMapperFactory.createUseJSONDates();


        puts( mapper.writeValueAsString( user ) );


        //Now to write and then read this as a file.

        File file = File.createTempFile( "user", ".json" );

        mapper.writeValue( file, user );

        Object userFromFile = mapper.readValue( file, Object.class );

        puts( "userFromFile", "type", userFromFile.getClass(), "value", userFromFile );

        Map<String, Object> map = (Map<String, Object>) mapper.readValue( file, Map.class );

        puts( "userFromFile", "type", map.getClass(), "value", map );


        puts( "userFromFile.name", "type", map.get("name").getClass(),
                "value", map.get("name") );


        puts( "userFromFile.birthDate", "type", map.get("birthDate").getClass(),
                "value", map.get("birthDate") );


        puts( "userFromFile.gender", "type", map.get("gender").getClass(),
                "value", map.get("gender") );


        User userFromMap =
               MapObjectConversion.fromMap(
                       map, User.class);

        puts ( userFromMap );

    }


    public static void part6() throws Exception {

        puts ("\n\n\n", "\npart5");

        ObjectMapper mapper = ObjectMapperFactory.createUseJSONDates();


        final User diana = BeanUtils.copy( user );
        final User rick = BeanUtils.copy( user );
        diana.getName().setFirst( "Diana" );
        diana.setGender( User.Gender.FEMALE );
        rick.getName().setFirst( "Rick" );
        diana.setBirthDate( Dates.getUSDate( 8, 21, 1984 ) );


        File file = File.createTempFile( "userList", ".json" );

        List<User> users = Lists.list( diana, rick );

        mapper.writeValue( file, users  );


        List<User> userList = mapper.readValue( file, List.class, User.class  );


        puts (userList);

        puts ( mapper.writeValueAsString( userList ) );


    }


    public static void main( String... args ) throws Exception {

        part1();
        part2();
        part3();
        part4();
        part5();

    }
}

Annotations

Working with annotations. Boon in general and Boon JSON support specifically is not driven entirely by annotations. There is both aJsonParserFactory and a JsonSerializerFactory and with those you can override certain behaviors of JSON parsing and serializing.
There are some annotations that Boon JSON does recognize and they are JsonIgnoreJsonInclude and JsonIncludeProperties. These JSON properties exist in Boon, but Boon will also recognize these annotations from JsonSmart and Jackson and handle them the same way.
By default (can be overridden with the factory) Boon will not write out nulls, empty lists or values that are default values (int primitive has a default of 0, boolean primitive has a default of false). If you want a value to be written out even if it is empty, null, false or 0, you can use the @JsonInclude annotation.
Boon by default outputs all properties and/or fields of an object. Let's say you had an employee directory and an employee has a SSN. You don't want to output an SSN so you can leave it out with a @JsonIgnore. Let's show how these work in practice.
Continuing our example before, let's create an SSN that we don't want output with JsonIgnore and a status string that we want written even if it is null or empty.
Using @JsonIgnore and @JsonInclude
  public class User {

      @JsonIgnore
      private String ssn = "555-55-5555";

      @JsonInclude
      private String status = null;
Write them out
      /* Write users out to file. */
      mapper.writeValue( file, users  );

      /* Reader Users back from file. */
      List<User> userList = mapper.readValue( file, List.class, User.class  );


      puts ("userListBeansReadFromFile", userList);

      /* Inspect the JSON of the users from the file. */
      puts ("usersFromFileAsJSON", mapper.writeValueAsString( userList ) );
Output
usersFromFileAsJSON 
[
    {
        "status": null,
        "gender": "FEMALE",
        "name": {
            "first": "Diana",
            "last": "Hightower"
        },
        "verified": true,
        "birthDate": "1984-08-22T00:00:00.910Z"
    },
    {
        "status": null,
        "gender": "MALE",
        "name": {
            "first": "Rick",
            "last": "Hightower"
        },
        "verified": true,
        "birthDate": "1980-05-26T00:00:00.822Z"
    }
]

Complete code listing so far

package org.boon.json;

import org.boon.Lists;
import org.boon.core.Dates;
import org.boon.core.reflection.BeanUtils;
import org.boon.core.reflection.MapObjectConversion;
import org.boon.json.annotations.JsonIgnore;
import org.boon.json.annotations.JsonInclude;

import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static org.boon.Boon.puts;

/**
 * Created by rick on 1/4/14.
 */
public class JsonTutorial {


    public static class MyBean {
        String name = "Rick";

        @Override
        public String toString() {
            return "MyBean{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }


    public static class User {

        @JsonIgnore
        private String ssn = "555-55-5555";

        @JsonInclude
        private String status = null;

        public enum Gender {MALE, FEMALE}



        public static class Name {
            private String first, last;

            public Name( String _first, String _last ) {
                this.first = _first;
                this.last = _last;
            }

            public String getFirst() {
                return first;
            }

            public String getLast() {
                return last;
            }

            public void setFirst( String s ) {
                first = s;
            }

            public void setLast( String s ) {
                last = s;
            }

            @Override
            public String toString() {
                return "Name{" +
                        "first='" + first + '\'' +
                        ", last='" + last + '\'' +
                        '}';
            }
        }

        private Gender gender;
        private Name name;
        private boolean verified;
        private Date birthDate;

        public Name getName() {
            return name;
        }

        public boolean isVerified() {
            return verified;
        }

        public Gender getGender() {
            return gender;
        }

        public void setName( Name n ) {
            name = n;
        }

        public void setVerified( boolean b ) {
            verified = b;
        }

        public void setGender( Gender g ) {
            gender = g;
        }

        public Date getBirthDate() {
            return birthDate;
        }

        public void setBirthDate( Date birthDate ) {
            this.birthDate = birthDate;
        }

        @Override
        public String toString() {
            return "User{" +
                    "gender=" + gender +
                    ", name=" + name +
                    ", verified=" + verified +
                    ", birthDate=" + birthDate +
                    '}';
        }
    }


    static User user = new User();

    static {
        user.setGender( User.Gender.MALE );
        user.setName( new User.Name( "Richard", "Hightower" ) );
        user.setVerified( true );
        user.setBirthDate( Dates.getUSDate( 5, 25, 1980 ) );
    }

    public static void part1() throws Exception {


        MyBean myBean = new MyBean();
        File dst = File.createTempFile( "emp", ".json" );

        ObjectMapper mapper = ObjectMapperFactory.create();

        puts( "json string", mapper.writeValueAsString( myBean ) );

        mapper.writeValue( dst, myBean ); // where 'dst' can be File, OutputStream or Writer


        File src = dst;
        MyBean value = mapper.readValue( src, MyBean.class ); // 'src' can be File, InputStream, Reader, String

        puts( "mybean", value );


        Object root = mapper.readValue( src, Object.class );
        Map<String, Object> rootAsMap = mapper.readValue( src, Map.class );

        puts( "root", root );
        puts( "rootAsMap", rootAsMap );


        MyBean myBean1 = new MyBean();
        myBean1.name = "Diana";
        MyBean myBean2 = new MyBean();
        myBean2.name = "Rick";

        dst = File.createTempFile( "empList", ".json" );

        final List<MyBean> list = Lists.list( myBean1, myBean2 );

        puts( "json string", mapper.writeValueAsString( list ) );

        mapper.writeValue( dst, list );

        src = dst;

        List<MyBean> beans = mapper.readValue( src, List.class, MyBean.class );

        puts( "mybeans", beans );


    }

    public static void part2() throws Exception {

        ObjectMapper mapper = ObjectMapperFactory.create();


        puts( mapper.writeValueAsString( user ) );


        //Now to write and then read this as a file.

        File file = File.createTempFile( "user", ".json" );

        mapper.writeValue( file, user );

        User userFromFile = mapper.readValue( file, User.class );

        puts( "userFromFile", userFromFile );


        Path path = Paths.get( file.toString() );
        InputStream inputStream = Files.newInputStream( path );

        User userFromInput = mapper.readValue( inputStream, User.class );
        puts( "userFromInput", userFromInput );


        Reader reader = Files.newBufferedReader( path, StandardCharsets.UTF_8 );
        User userFromReader = mapper.readValue( reader, User.class );

        puts( "userFromReader", userFromReader );


    }

    public static void part3() throws Exception {
        part3_1();
        part3_2();
    }

    public static void part3_1() throws Exception {

        ObjectMapper mapper = ObjectMapperFactory.create();
        puts( mapper.writeValueAsString( user ) );

        User user2 = mapper.readValue( mapper.writeValueAsString( user ), User.class );

        puts( user2 );
    }


    public static void part3_2() throws Exception {

        ObjectMapper mapper = ObjectMapperFactory.createUseJSONDates();
        puts( mapper.writeValueAsString( user ) );

        User user2 = mapper.readValue( mapper.writeValueAsString( user ), User.class );

        puts( user2 );

    }

    public static void part5() throws Exception {

        puts ("\n\n\n", "\npart5");

        ObjectMapper mapper = ObjectMapperFactory.createUseJSONDates();


        final User diana = BeanUtils.copy( user );
        final User rick = BeanUtils.copy( user );
        diana.getName().setFirst( "Diana" );
        rick.getName().setFirst( "Rick" );
        diana.setBirthDate( Dates.getUSDate( 8, 21, 1984 ) );


        File file = File.createTempFile( "userList", ".json" );

        List<User> users = Lists.list( diana, rick );

        mapper.writeValue( file, users  );


        List<User> userList = mapper.readValue( file, List.class, User.class  );


        puts (userList);

        puts ( mapper.writeValueAsString( userList ) );


    }

    public static void part4() throws Exception {

        ObjectMapper mapper = ObjectMapperFactory.createUseJSONDates();


        puts( mapper.writeValueAsString( user ) );


        //Now to write and then read this as a file.

        File file = File.createTempFile( "user", ".json" );

        mapper.writeValue( file, user );

        Object userFromFile = mapper.readValue( file, Object.class );

        puts( "userFromFile", "type", userFromFile.getClass(), "value", userFromFile );

        Map<String, Object> map = (Map<String, Object>) mapper.readValue( file, Map.class );

        puts( "userFromFile", "type", map.getClass(), "value", map );


        puts( "userFromFile.name", "type", map.get("name").getClass(),
                "value", map.get("name") );


        puts( "userFromFile.birthDate", "type", map.get("birthDate").getClass(),
                "value", map.get("birthDate") );


        puts( "userFromFile.gender", "type", map.get("gender").getClass(),
                "value", map.get("gender") );


        User userFromMap =
               MapObjectConversion.fromMap(
                       map, User.class);

        puts ( userFromMap );

    }


    public static void part6() throws Exception {

        puts ("\n\n\n", "\npart6");

        ObjectMapper mapper = ObjectMapperFactory.createUseJSONDates();


        final User diana = BeanUtils.copy( user );
        final User rick = BeanUtils.copy( user );
        diana.getName().setFirst( "Diana" );
        diana.setGender( User.Gender.FEMALE );
        rick.getName().setFirst( "Rick" );
        diana.setBirthDate( Dates.getUSDate( 8, 21, 1984 ) );


        File file = File.createTempFile( "userList", ".json" );

        List<User> users = Lists.list( diana, rick );

        mapper.writeValue( file, users  );


        List<User> userList = mapper.readValue( file, List.class, User.class  );


        puts (userList);

        puts ( mapper.writeValueAsString( userList ) );


    }

    public static void part7() throws Exception {

        puts ("\n\n\n", "\npart7");

        ObjectMapper mapper = ObjectMapperFactory.createUseAnnotations( true );


        /* Create two users. */
        final User diana = BeanUtils.copy( user );
        final User rick = BeanUtils.copy( user );
        diana.getName().setFirst( "Diana" );
        diana.setGender( User.Gender.FEMALE );
        rick.getName().setFirst( "Rick" );
        diana.setBirthDate( Dates.getUSDate( 8, 21, 1984 ) );

        File file = File.createTempFile( "userList", ".json" );
        List<User> users = Lists.list( diana, rick );


        /* Inspect the JSON of the users from the file. */
        puts ("users", mapper.writeValueAsString( users ) );


        /* Write users out to file. */
        mapper.writeValue( file, users  );

        /* Reader Users back from file. */
        List<User> userList = mapper.readValue( file, List.class, User.class  );


        puts ("userListBeansReadFromFile", userList);

        /* Inspect the JSON of the users from the file. */
        puts ("usersFromFileAsJSON", mapper.writeValueAsString( userList ) );


    }

    public static void main( String... args ) throws Exception {

        part1();
        part2();
        part3();
        part4();
        part5();
        part6();
        part7();


    }
}
Output so far
json string {"name":"Rick"} 
mybean MyBean{name='Rick'} 
root {name=Rick} 
rootAsMap {name=Rick} 
json string [{"name":"Diana"},{"name":"Rick"}] 
mybeans [MyBean{name='Diana'}, MyBean{name='Rick'}] 
{"ssn":"555-55-5555","gender":"MALE","name":{"first":"Richard","last":"Hightower"},"verified":true,"birthDate":328147200833} 
userFromFile User{gender=MALE, name=Name{first='Richard', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980} 
userFromInput User{gender=MALE, name=Name{first='Richard', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980} 
userFromReader User{gender=MALE, name=Name{first='Richard', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980} 
{"ssn":"555-55-5555","gender":"MALE","name":{"first":"Richard","last":"Hightower"},"verified":true,"birthDate":328147200833} 
User{gender=MALE, name=Name{first='Richard', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980} 
{"ssn":"555-55-5555","gender":"MALE","name":{"first":"Richard","last":"Hightower"},"verified":true,"birthDate":"1980-05-26T00:00:00.833Z"} 
User{gender=MALE, name=Name{first='Richard', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980} 
{"ssn":"555-55-5555","gender":"MALE","name":{"first":"Richard","last":"Hightower"},"verified":true,"birthDate":"1980-05-26T00:00:00.833Z"} 
userFromFile type class org.boon.core.value.LazyValueMap value {ssn=555-55-5555, gender=MALE, birthDate=Sun May 25 17:00:00 PDT 1980, verified=true, name={last=Hightower, first=Richard}} 
userFromFile type class org.boon.core.value.LazyValueMap value {ssn=555-55-5555, gender=MALE, birthDate=Sun May 25 17:00:00 PDT 1980, verified=true, name={last=Hightower, first=Richard}} 
userFromFile.name type class org.boon.core.value.LazyValueMap value {last=Hightower, first=Richard} 
userFromFile.birthDate type class java.util.Date value Sun May 25 17:00:00 PDT 1980 
userFromFile.gender type class java.lang.String value MALE 
User{gender=MALE, name=Name{first='Richard', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980} 



 
part5 
[User{gender=MALE, name=Name{first='Diana', last='Hightower'}, verified=true, birthDate=Tue Aug 21 17:00:00 PDT 1984}, User{gender=MALE, name=Name{first='Rick', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980}] 
[{"ssn":"555-55-5555","gender":"MALE","name":{"first":"Diana","last":"Hightower"},"verified":true,"birthDate":"1984-08-22T00:00:00.989Z"},{"ssn":"555-55-5555","gender":"MALE","name":{"first":"Rick","last":"Hightower"},"verified":true,"birthDate":"1980-05-26T00:00:00.833Z"}] 



 
part6 
[User{gender=FEMALE, name=Name{first='Diana', last='Hightower'}, verified=true, birthDate=Tue Aug 21 17:00:00 PDT 1984}, User{gender=MALE, name=Name{first='Rick', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980}] 
[{"ssn":"555-55-5555","gender":"FEMALE","name":{"first":"Diana","last":"Hightower"},"verified":true,"birthDate":"1984-08-22T00:00:00.991Z"},{"ssn":"555-55-5555","gender":"MALE","name":{"first":"Rick","last":"Hightower"},"verified":true,"birthDate":"1980-05-26T00:00:00.833Z"}] 



 
part7 
users [{"status":null,"gender":"FEMALE","name":{"first":"Diana","last":"Hightower"},"verified":true,"birthDate":"1984-08-22T00:00:00.992Z"},{"status":null,"gender":"MALE","name":{"first":"Rick","last":"Hightower"},"verified":true,"birthDate":"1980-05-26T00:00:00.833Z"}] 
userListBeansReadFromFile [User{gender=FEMALE, name=Name{first='Diana', last='Hightower'}, verified=true, birthDate=Tue Aug 21 17:00:00 PDT 1984}, User{gender=MALE, name=Name{first='Rick', last='Hightower'}, verified=true, birthDate=Sun May 25 17:00:00 PDT 1980}] 
usersFromFileAsJSON [{"status":null,"gender":"FEMALE","name":{"first":"Diana","last":"Hightower"},"verified":true,"birthDate":"1984-08-22T00:00:00.992Z"},{"status":null,"gender":"MALE","name":{"first":"Rick","last":"Hightower"},"verified":true,"birthDate":"1980-05-26T00:00:00.833Z"}] 

Process finished with exit code 0

Primitive parsing

At times it is nice to have a light weight parser that can handling Java primitive types, Strings, etc.
Boon JSON can read int, float, double, long, int arrays, dates, strings, etc.
      ObjectMapper mapper = ObjectMapperFactory.create();


      String intStr = "123456";

      int someNumber = mapper.parser().parseInt( intStr );

      boolean ok = someNumber == 123456 || die( "" + someNumber );


      String jsonArray = "[0,1,2,3,4,5,6,7,8]";

      int [] intArray = mapper.parser().parseIntArray( jsonArray );

      ok |= Arrays.equals( new int[]{1,2,3,4,5,6,7,8}, intArray );


      String jsonMap = "{\"race\":true, \"speedup\": false, \"name\": \"bob\"}";

      Map <String, Object> map  = mapper.parser().parseMap( jsonMap );

      ok |= ( map.get("race") == true  && map.get("name").equals( "bob" ) )  || die(map.toString());

      puts("ok?", ok);
The main interface to Boon parsing is not ObjectMapper, but JsonParser. The ObjectMapper interface is the one most people are familiar with thanks to the success of Jackson.
You could easily use JsonParser to read configuration settings stored as strings in a database or a properties files, etc. It allows you to parse arrays, strings, maps easily. No fuss no muss. No need for object serialization or annotations. Boon's JsonParser is first and foremost a fast and lightweight parser.
Notice as you ponder the overview of JsonParser that it supports BigDecmimal and BigInteger as well.

Overview of what the parser can do

package org.boon.json;

import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.List;
import java.util.Map;

public interface JsonParser {


    Map<String, Object> parseMap( String value );
    Map<String, Object> parseMap( char [] value );
    Map<String, Object> parseMap( byte[] value );
    Map<String, Object> parseMap( byte[] value, Charset charset );
    Map<String, Object> parseMap( InputStream value, Charset charset );
    Map<String, Object> parseMap( CharSequence value );
    Map<String, Object> parseMap( InputStream value );
    Map<String, Object> parseMap( Reader value );
    Map<String, Object> parseMapFromFile(  String file );

    <T> List<T>  parseList(  Class<T> componentType, String jsonString );
    <T> List<T>  parseList(  Class<T> componentType, InputStream input );
    <T> List<T>  parseList(  Class<T> componentType, Reader reader );
    <T> List<T>  parseList(  Class<T> componentType, InputStream input, Charset charset );
    <T> List<T>  parseList(  Class<T> componentType, byte[] jsonBytes );
    <T> List<T>  parseList(  Class<T> componentType, byte[] jsonBytes, Charset charset );
    <T> List<T>  parseList(  Class<T> componentType, char[] chars );
    <T> List<T>  parseList(  Class<T> componentType, CharSequence jsonSeq );
    <T> List<T>  parseListFromFile(  Class<T> componentType, String fileName );

    <T> T parse( Class<T> type, String jsonString );
    <T> T parse( Class<T> type, byte[] bytes );
    <T> T parse( Class<T> type, byte[] bytes, Charset charset );
    <T> T parse( Class<T> type, CharSequence charSequence );
    <T> T parse( Class<T> type, char[] chars );
    <T> T parse( Class<T> type, Reader reader );
    <T> T parse( Class<T> type, InputStream input );
    <T> T parse( Class<T> type, InputStream input, Charset charset );
    <T> T parseDirect( Class<T> type, byte[] value );
    <T> T parseAsStream( Class<T> type, byte[] value );
    <T> T parseFile( Class<T> type,  String fileName);



    int  parseInt(  String jsonString );
    int  parseInt(  InputStream input );
    int  parseInt(  InputStream input, Charset charset );
    int  parseInt(  byte[] jsonBytes );
    int  parseInt(  byte[] jsonBytes, Charset charset );
    int  parseInt(  char[] chars );
    int  parseInt(  CharSequence jsonSeq );
    int  parseIntFromFile(  String fileName );

    long  parseLong(  String jsonString );
    long  parseLong(  InputStream input );
    long  parseLong(  InputStream input, Charset charset );
    long  parseLong(  byte[] jsonBytes );
    long  parseLong(  byte[] jsonBytes, Charset charset );
    long  parseLong(  char[] chars );
    long  parseLong(  CharSequence jsonSeq );
    long  parseLongFromFile(  String fileName );

    double  parseDouble(  String value );
    double  parseDouble(  InputStream value );
    double  parseDouble(  byte[] value );
    double  parseDouble(  char[] value );
    double  parseDouble(  CharSequence value );
    double  parseDouble(  byte[] value, Charset charset );
    double  parseDouble(  InputStream value, Charset charset );
    double  parseDoubleFromFile(  String fileName );

    float  parseFloat(  String value );
    float  parseFloat(  InputStream value );
    float  parseFloat(  byte[] value );
    float  parseFloat(  char[] value );
    float  parseFloat(  CharSequence value );
    float  parseFloat(  byte[] value, Charset charset );
    float  parseFloat(  InputStream value, Charset charset );
    float  parseFloatFromFile(  String fileName );


    BigDecimal  parseBigDecimal(  String value );
    BigDecimal  parseBigDecimal(  InputStream value );
    BigDecimal  parseBigDecimal(  byte[] value );
    BigDecimal  parseBigDecimal(  char[] value );
    BigDecimal  parseBigDecimal(  CharSequence value );
    BigDecimal  parseBigDecimal(  byte[] value, Charset charset );
    BigDecimal  parseBigDecimal(  InputStream value, Charset charset );
    BigDecimal  parseBigDecimalFromFile(  String fileName );


    BigInteger  parseBigInteger(  String value );
    BigInteger  parseBigInteger(  InputStream value );
    BigInteger  parseBigInteger(  byte[] value );
    BigInteger  parseBigInteger(  char[] value );
    BigInteger  parseBigInteger(  CharSequence value );
    BigInteger  parseBigInteger(  byte[] value, Charset charset );
    BigInteger  parseBigInteger(  InputStream value, Charset charset );
    BigInteger  parseBigIntegerFile(  String fileName );

    Date  parseDate(  String jsonString );
    Date  parseDate(  InputStream input );
    Date  parseDate(  InputStream input, Charset charset );
    Date  parseDate(  byte[] jsonBytes );
    Date  parseDate(  byte[] jsonBytes, Charset charset );
    Date  parseDate(  char[] chars );
    Date  parseDate(  CharSequence jsonSeq );
    Date  parseDateFromFile(  String fileName );



    short  parseShort (  String jsonString );
    byte   parseByte  (  String jsonString );
    char   parseChar  (  String jsonString );
    <T extends Enum> T  parseEnum (  Class<T> type, String jsonString );

    public char     [] parseCharArray   ( String jsonString );
    public byte     [] parseByteArray   ( String jsonString );
    public short    [] parseShortArray  ( String jsonString );
    public int      [] parseIntArray    ( String jsonString );
    public float    [] parseFloatArray  ( String jsonString );
    public double   [] parseDoubleArray ( String jsonString );
    public long     [] parseLongArray   ( String jsonString );


    Object parse(  String jsonString );
    Object parse(  byte[] bytes );
    Object parse(  byte[] bytes, Charset charset );
    Object parse(  CharSequence charSequence );
    Object parse(  char[] chars );
    Object parse(  Reader reader );
    Object parse(  InputStream input );
    Object parse(  InputStream input, Charset charset );
    Object parseDirect(  byte[] value );
    Object parseAsStream(  byte[] value );
    Object parseFile(  String fileName);


    void close();

}

Advanced JSON Boon

With Boon you can customize the output and input with JsonParserFactory and JsonSerializerFactory as follows:
You can basically install custom field serializers and type serializer on the factory:
      AllTypes foo = new AllTypes ();
      foo.ingnoreMe = "THIS WILL NOT PASS";
      foo.ignoreMe2 = "THIS WILL NOT PASS EITHER";
      foo.ignoreMe3 = "THIS WILL NOT PASS TOO";

      foo.setDate ( new Date() );
      foo.setBar ( FooEnum.BAR );
      foo.setFoo ( FooEnum.FOO );
      foo.setString ( "Hi Mom" );
      AllTypes foo2 = BeanUtils.copy( foo );
      foo.setAllType ( foo2 );
      foo2.setString ( "Hi Dad" );
      foo.setAllTypes ( Lists.list( BeanUtils.copy( foo2 ), BeanUtils.copy( foo2 )) );

      final JsonSerializer serializer = new JsonSerializerFactory ()
              .useAnnotations ()
              .addFilter ( new FieldFilter () {
                  @Override
                  public boolean include ( Object parent, FieldAccess fieldAccess ) {
                      if ( fieldAccess.getName().equals( "ignoreMe3" ) ) {
                          return false;
                      } else {
                          return true;
                      }
                  }
              } ).addPropertySerializer ( new CustomFieldSerializer () {

                  @Override
                  public boolean serializeField ( JsonSerializerInternal serializer, Object parent,
                                                  FieldAccess fieldAccess, CharBuf builder ) {
                      if ( fieldAccess.getType ().equals ( long.class ) &&
                              fieldAccess.getName ().endsWith ( "Date" ) ) {

                          builder.addJsonFieldName ( fieldAccess.getName () );
                          Date date = Conversions.toDate ( fieldAccess.getLong ( parent ) );

                          final String jsonDateString = Dates.jsonDate ( date );

                          builder.add ( jsonDateString );
                          return true;
                      } else {
                          return false;
                      }
                  }
              } ).addTypeSerializer ( FooBasket.class, new AbstractCustomObjectSerializer ( FooBasket.class ) {

                  @Override
                  public void serializeObject ( JsonSerializerInternal serializer, Object instance, CharBuf builder ) {
                      builder.addString ( "[\"wiki\",\"wiki\",\"wiki\"]" );
                  }
              } )
              .create ();
      String json = serializer.serialize ( foo ).toString ();
       puts (json);

      boolean ok = json.contains  ("[\"wiki\",\"wiki\",\"wiki\"]" ) || die();


      puts (json);
      AllTypes testMe = jsonParser.parse( AllTypes.class, json);

       ok |= testMe.equals ( foo ) || die();




      ok |= testMe.ingnoreMe == null || die();

      puts (testMe.ignoreMe2);
      ok |= testMe.ignoreMe2 == null || die();

      puts (testMe.ignoreMe3);
      ok |= testMe.ignoreMe3 == null || die();

      ok |= testMe.someDate > 0 || die();
This is just a quick example. A full listing and explanation is due, but that would not fit in a five minute discussion. :)
The AllType class used in the example:
package org.boon.json;

import org.boon.json.annotations.JsonIgnore;
import org.boon.json.annotations.JsonIgnoreProperties;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@JsonIgnoreProperties ("ignoreMe2")
public class AllTypes {


    public FooBasket getFooBasket () {
        return fooBasket;
    }

    public void setFooBasket ( FooBasket fooBasket ) {
        this.fooBasket = fooBasket;
    }

    FooBasket fooBasket = new FooBasket ();

    String ignoreMe3;

    String ignoreMe2;

    int myInt;
    boolean myBoolean;
    short myShort;
    long myLong;
    String string;
    String string2;
    BigDecimal bigDecimal;
    BigInteger bigInteger;
    Date date;

    float myFloat;
    double myDouble;
    byte myByte;

    FooEnum foo;
    FooEnum bar;

    @JsonIgnore
    String ingnoreMe;


    long someDate = new Date (  ).getTime ();



    AllTypes allType;

    List<AllTypes> allTypes = new ArrayList<> (  );


    public String getString2 () {
        return string2;
    }

    public void setString2 ( String string2 ) {
        this.string2 = string2;
    }

    public List<AllTypes> getAllTypes () {
        return allTypes;
    }

    public void setAllTypes ( List<AllTypes> allTypes ) {
        this.allTypes = allTypes;
    }

    public AllTypes getAllType () {
        return allType;
    }

    public void setAllType ( AllTypes allType ) {
        this.allType = allType;
    }

    public byte getMyByte () {
        return myByte;
    }

    public void setMyByte ( byte myByte ) {
        this.myByte = myByte;
    }

    public int getMyInt () {
        return myInt;
    }

    public void setMyInt ( int myInt ) {
        this.myInt = myInt;
    }

    public boolean isMyBoolean () {
        return myBoolean;
    }

    public void setMyBoolean ( boolean myBoolean ) {
        this.myBoolean = myBoolean;
    }

    public short getMyShort () {
        return myShort;
    }

    public void setMyShort ( short myShort ) {
        this.myShort = myShort;
    }

    public long getMyLong () {
        return myLong;
    }

    public void setMyLong ( long myLong ) {
        this.myLong = myLong;
    }

    public String getString () {
        return string;
    }

    public void setString ( String string ) {
        this.string = string;
    }


    public float getMyFloat () {
        return myFloat;
    }

    public void setMyFloat ( float myFloat ) {
        this.myFloat = myFloat;
    }

    public double getMyDouble () {
        return myDouble;
    }

    public void setMyDouble ( double myDouble ) {
        this.myDouble = myDouble;
    }


    public BigDecimal getBigDecimal () {
        return bigDecimal;
    }

    public void setBigDecimal ( BigDecimal bigDecimal ) {
        this.bigDecimal = bigDecimal;
    }

    public BigInteger getBigInteger () {
        return bigInteger;
    }

    public void setBigInteger ( BigInteger bigInteger ) {
        this.bigInteger = bigInteger;
    }


    public Date getDate () {
        return date;
    }

    public void setDate ( Date date ) {
        this.date = date;
    }


    public FooEnum getFoo () {
        return foo;
    }

    public void setFoo ( FooEnum foo ) {
        this.foo = foo;
    }

    public FooEnum getBar () {
        return bar;
    }

    public void setBar ( FooEnum bar ) {
        this.bar = bar;
    }


    @Override
    public boolean equals ( Object o ) {
        if ( this == o ) return true;
        if ( !( o instanceof AllTypes ) ) return false;

        AllTypes allTypes1 = ( AllTypes ) o;

        if ( myBoolean != allTypes1.myBoolean ) return false;
        if ( myByte != allTypes1.myByte ) return false;
        if ( Double.compare ( allTypes1.myDouble, myDouble ) != 0 ) return false;
        if ( Float.compare ( allTypes1.myFloat, myFloat ) != 0 ) return false;
        if ( myInt != allTypes1.myInt ) return false;
        if ( myLong != allTypes1.myLong ) return false;
        if ( myShort != allTypes1.myShort ) return false;
        if ( bigDecimal != null ? !bigDecimal.equals ( allTypes1.bigDecimal ) : allTypes1.bigDecimal != null )
            return false;
        if ( bigInteger != null ? !bigInteger.equals ( allTypes1.bigInteger ) : allTypes1.bigInteger != null )
            return false;
        if ( string != null ? !string.equals ( allTypes1.string ) : allTypes1.string != null ) return false;
        if ( string2 != null ? !string2.equals ( allTypes1.string2 ) : allTypes1.string2 != null ) return false;

        if (allTypes == null && allTypes1.allTypes.size () == 0) {
            return true;
        } else {

            if ( allTypes != null ? !allTypes.equals ( allTypes1.allTypes ) : allTypes1.allTypes != null ) return false;

        }

        if ( date != null  && allTypes1.date!=null) {

            long delta = Math.abs ( date.getTime () - allTypes1.date.getTime ());

            if ( delta < 1000) {
                return true;
            } else {
                return false;
            }

        }

       if ( allType != null ? !allType.equals ( allTypes1.allType ) : allTypes1.allType != null ) return false;
        if ( bar != allTypes1.bar ) return false;
        if ( foo != allTypes1.foo ) return false;


        return true;
    }

    @Override
    public int hashCode () {
        int result;
        long temp;
        result = myInt;
        result = 31 * result + ( myBoolean ? 1 : 0 );
        result = 31 * result + ( int ) myShort;
        result = 31 * result + ( int ) ( myLong ^ ( myLong >>> 32 ) );
        result = 31 * result + ( string != null ? string.hashCode () : 0 );
        result = 31 * result + ( string2 != null ? string2.hashCode () : 0 );
        result = 31 * result + ( bigDecimal != null ? bigDecimal.hashCode () : 0 );
        result = 31 * result + ( bigInteger != null ? bigInteger.hashCode () : 0 );
        result = 31 * result + ( date != null ? date.hashCode () : 0 );
        result = 31 * result + ( myFloat != +0.0f ? Float.floatToIntBits ( myFloat ) : 0 );
        temp = Double.doubleToLongBits ( myDouble );
        result = 31 * result + ( int ) ( temp ^ ( temp >>> 32 ) );
        result = 31 * result + ( int ) myByte;
        result = 31 * result + ( foo != null ? foo.hashCode () : 0 );
        result = 31 * result + ( bar != null ? bar.hashCode () : 0 );
        result = 31 * result + ( allType != null ? allType.hashCode () : 0 );
        result = 31 * result + ( allTypes != null ? allTypes.hashCode () : 0 );
        return result;
    }

    @Override
    public String toString () {
        return "AllTypes{" +
                "myInt=" + myInt +
                ", myBoolean=" + myBoolean +
                ", myShort=" + myShort +
                ", myLong=" + myLong +
                ", string='" + string + '\'' +
                ", string2='" + string2 + '\'' +
                ", bigDecimal=" + bigDecimal +
                ", bigInteger=" + bigInteger +
                ", date=" + date +
                ", myFloat=" + myFloat +
                ", myDouble=" + myDouble +
                ", myByte=" + myByte +
                ", foo=" + foo +
                ", bar=" + bar +
                ", allType=" + allType +
                ", allTypes=" + allTypes +
                '}';
    }
}

Json parse and serialize options

You customize the settings via the factories. You can customize if the parser and serializer uses fields, properties or both. You can also customize how the parser should parser the data (strict or relaxed or even ASCII PLIST style).
      JsonParserFactory jsonParserFactory = new JsonParserFactory()
              .useFieldsFirst().useFieldsOnly().usePropertiesFirst().usePropertyOnly() //one of these
              .plistStyle() //allow parsing of ASCII PList style files
              .lax() //allow loose parsing of JSON like JSON Smart
              .strict() //opposite of lax
              .setCharset( StandardCharsets.UTF_8 ) //Set the standard charset, defaults to UTF_8
              .setChop( true ) //chops up buffer overlay buffer (more discussion of this later)
              .setLazyChop( true ) //similar to chop but only does it after map.get
              ;

      JsonSerializerFactory jsonSerializerFactory = new JsonSerializerFactory()
              .useFieldsFirst().useFieldsOnly().usePropertiesFirst().usePropertyOnly() //one of these
              //.addPropertySerializer(  )  customize property output
              //.addTypeSerializer(  )      customize type output
              .useJsonFormatForDates() //use json dates
              //.addFilter(  )   add a property filter to exclude properties
              .includeEmpty().includeNulls().includeDefaultValues() //override defaults
              .handleComplexBackReference() //uses identity map to track complex back reference and avoid them
              .setHandleSimpleBackReference( true ) //looks for simple back reference for parent
              .setCacheInstances( true ) //turns on caching for immutable objects
              ;
Once you have the factories you can create parsers, serializers or object mappers with them as follows:
      //You can use parser and serializer directly.
      final JsonParser jsonParser = jsonParserFactory.create();
      final JsonSerializer jsonSerializer = jsonSerializerFactory.create();

      File file = File.createTempFile( "userList", ".json" );
      String jsonString = jsonSerializer.serialize( users ).toString();
      IO.write( IO.path( file.toString()), jsonString);
      List<User> users2 = jsonParser.parseListFromFile( User.class, file.toString() );

      // Or you can pass them to the ObjectMapper interface you know and love, 
      // just pass the factories to it.
      ObjectMapper mapper = ObjectMapperFactory.create(jsonParserFactory, jsonSerializerFactory);


      mapper.writeValue( file, users  );
      List<User> userList = mapper.readValue( file, List.class, User.class  );
      puts (userList);
      puts ( mapper.writeValueAsString( userList ) );

Boon speed

Boon is the all around fastest JSON parser out of GSON, Jackson and JsonSmart (so far). Boon now has input stream, reader, byte[], char[], CharSequence and String support.
Run on 17" 2011 Mac Book Pro with SSD and 16 GB or RAM.

1/5/2014

String

Testing against a 1.7 MB string.
java -jar target/microbenchmarks.jar ".string.Catalog" -wi 3 -i 5 -f 1 -t 8
Benchmark                                      Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.s.StatelessBoonBenchMark.citmCatalog    thrpt   8         5    1      979.087      234.875    ops/s
i.g.j.s.BoonBenchmark.citmCatalog             thrpt   8         5    1      975.467      155.524    ops/s
i.g.j.s.BoonClassicBenchmark.citmCatalog      thrpt   8         5    1      724.397       76.153    ops/s


i.g.j.s.JsonSmartBenchmark.citmCatalog        thrpt   8         5    1      423.947       45.707    ops/s
i.g.j.s.GSONBenchmark.citmCatalog             thrpt   8         5    1      373.203       38.523    ops/s
i.g.j.s.JacksonASTBenchmark.citmCatalog       thrpt   8         5    1      269.490       30.313    ops/s
i.g.j.s.JacksonObjectBenchmark.citmCatalog    thrpt   8         5    1      263.187       95.644    ops/s
Boon is 3x+ some of the competitors.
Jackson did so poorly that I ran it again by itself.
Benchmark                                      Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.s.JacksonASTBenchmark.citmCatalog       thrpt   8         5    1      314.703       96.497    ops/s
i.g.j.s.JacksonObjectBenchmark.citmCatalog    thrpt   8         5    1      381.953       11.466    ops/s
Then to be fair to boon, I ran the two top performing Boon parser configurations as well
Benchmark                                      Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.s.BoonBenchmark.citmCatalog             thrpt   8         5    1     1249.423      215.237    ops/s
i.g.j.s.StatelessBoonBenchMark.citmCatalog    thrpt   8         5    1     1074.957      255.704    ops/s
Then the run off test:
Fastest Jackson against Fastest Boon
Benchmark                             Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.s.BoonBenchmark.citmCatalog    thrpt   8         5    1     1306.067       75.496    ops/s
Benchmark                                      Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.s.JacksonObjectBenchmark.citmCatalog    thrpt   8         5    1      369.557       16.925    ops/s
Boon maintains its 4x status over Jackson for this test. citmCatalog is a 1.7 MB file.
Boon is 4x faster when you run them by themselves.
Testing against a 2K JSON file
java -jar target/microbenchmarks.jar ".string.medium" -wi 3 -i 5 -f 3 -t 8
Benchmark                                 Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.s.StatelessBoonBenchMark.medium    thrpt   8        15    1   828614.167   113309.263    ops/s
i.g.j.s.BoonBenchmark.medium             thrpt   8        15    1   655723.022   113194.181    ops/s
i.g.j.s.BoonClassicBenchmark.medium      thrpt   8        15    1   544726.818    31969.515    ops/s


i.g.j.s.JsonSmartBenchmark.medium        thrpt   8        15    1   261257.857    15178.567    ops/s
i.g.j.s.JacksonASTBenchmark.medium       thrpt   8        15    1   244845.260     4459.778    ops/s
i.g.j.s.GSONBenchmark.medium             thrpt   8        15    1   242176.437     5552.595    ops/s
i.g.j.s.JacksonObjectBenchmark.medium    thrpt   8        15    1   239011.644     9544.070    ops/s
Boon is nearly 4x faster than Jackson in this configuration.
Now lets run the fastest boon against the fastest Jackson by themselves.
java -jar target/microbenchmarks.jar ".string.JacksonASTBenchmark.*medium" -wi 3 -i 5 -f 1 -t 8
Benchmark                              Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.s.JacksonASTBenchmark.medium    thrpt   8         5    1   285827.937    30910.474    ops/s
Now the fastest Boon
java -jar target/microbenchmarks.jar ".string.BoonBenchmark.*medium" -wi 3 -i 5 -f 1 -t 8
Benchmark                        Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.s.BoonBenchmark.medium    thrpt   8         5    1  1053372.327    16233.011    ops/s
The conclusion from 12/15/2013 to 1/4/2014 Boon is 100% faster than Boon, and where it was 50% to 100% faster than Jackson. Boon is now 200%, 300% and sometimes up to 400% faster than Jackson.
Boon wins by large margins when it comes to String parsing.

byte[] parsing

How does Boon do against the competitors when it is a byte[] instead of a String?
Benchmark                                  Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.b.BoonBenchmark.medium              thrpt   8         5    1   618123.037    29518.544    ops/s
i.g.j.b.JacksonObjectBenchmark.medium     thrpt   8         5    1   379202.950    22999.872    ops/s
i.g.j.b.JacksonASTBenchmark.medium        thrpt   8         5    1   293054.527    23981.011    ops/s
i.g.j.b.GSONBenchmark.medium              thrpt   8         5    1   205735.037   207194.930    ops/s
i.g.j.b.JsonSmartBenchmark.medium         thrpt   8         5    1   250384.043    25851.296    ops/s
Jackson does much better on this test than GSON and JsonSmart, but not better than Boon.
Now lets run them by themselves.
Benchmark                        Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.b.BoonBenchmark.medium    thrpt   8         5    1   827191.353    19862.004    ops/s
Benchmark                                 Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.b.JacksonObjectBenchmark.medium    thrpt   8         5    1   354519.703    28758.081    ops/s
Boon is over 2x faster at parsing byte arrays then Jackson is. (Boon has about 5 different ways to parse a byte[] and all are faster than Jackson.)
Jackson on all files from json.org.
java -jar target/microbenchmarks.jar ".bytes.JacksonObjectBenchmark.*" -wi 3 -i 5 -f 1 -t 8
Benchmark                                      Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.b.JacksonObjectBenchmark.actionLabel    thrpt   8         5    1   320460.340    72131.986    ops/s
i.g.j.b.JacksonObjectBenchmark.citmCatalog    thrpt   8         5    1      268.130       55.186    ops/s
i.g.j.b.JacksonObjectBenchmark.medium         thrpt   8         5    1   197295.940    22306.259    ops/s
i.g.j.b.JacksonObjectBenchmark.menu           thrpt   8         5    1   976004.950   268554.107    ops/s
i.g.j.b.JacksonObjectBenchmark.sgml           thrpt   8         5    1   572307.433   163097.782    ops/s
i.g.j.b.JacksonObjectBenchmark.small          thrpt   8         5    1  2275296.777   304454.266    ops/s
i.g.j.b.JacksonObjectBenchmark.webxml         thrpt   8         5    1   111176.677    19523.744    ops/s
i.g.j.b.JacksonObjectBenchmark.widget         thrpt   8         5    1   343268.823   119559.082    ops/s
Boon all files on JSON.org
java -jar target/microbenchmarks.jar ".bytes.BoonBenchmark.*" -wi 3 -i 5 -f 1 -t 8
Benchmark                             Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.b.BoonBenchmark.actionLabel    thrpt   8         5    1   618993.350    48683.336    ops/s
i.g.j.b.BoonBenchmark.citmCatalog    thrpt   8         5    1      492.307       80.017    ops/s
i.g.j.b.BoonBenchmark.medium         thrpt   8         5    1   458555.533    10036.229    ops/s
i.g.j.b.BoonBenchmark.menu           thrpt   8         5    1  1959464.230   505004.028    ops/s
i.g.j.b.BoonBenchmark.sgml           thrpt   8         5    1  1300516.190    59998.099    ops/s
i.g.j.b.BoonBenchmark.small          thrpt   8         5    1 10017411.120   171608.588    ops/s
i.g.j.b.BoonBenchmark.webxml         thrpt   8         5    1   253177.177   141918.931    ops/s
i.g.j.b.BoonBenchmark.widget         thrpt   8         5    1  1045186.440    95933.625    ops/s
i.g.j.b.BoonBenchmark.actionLabel             thrpt   8         5    1   618993.350    48683.336    ops/s
i.g.j.b.JacksonObjectBenchmark.actionLabel    thrpt   8         5    1   320460.340    72131.986    ops/s
Boon nearly 2x faster
1.7 MB
i.g.j.b.BoonBenchmark.citmCatalog             thrpt   8         5    1      492.307       80.017    ops/s
i.g.j.b.JacksonObjectBenchmark.citmCatalog    thrpt   8         5    1      268.130       55.186    ops/s
Boon nearly 2x faster
i.g.j.b.JacksonObjectBenchmark.small          thrpt   8         5    1  2275296.777   304454.266    ops/s
i.g.j.b.BoonBenchmark.small                   thrpt   8         5    1 10017411.120   171608.588    ops/s
Boon nearly 5x faster!
i.g.j.b.JacksonObjectBenchmark.widget         thrpt   8         5    1   343268.823   119559.082    ops/s
i.g.j.b.BoonBenchmark.widget                  thrpt   8         5    1  1045186.440    95933.625    ops/s
Boon almost 3x faster!
i.g.j.b.BoonBenchmark.medium                  thrpt   8         5    1   458555.533    10036.229    ops/s
i.g.j.b.JacksonObjectBenchmark.medium         thrpt   8         5    1   197295.940    22306.259    ops/s
Boon over 2x faster!
i.g.j.b.JacksonObjectBenchmark.menu           thrpt   8         5    1   976004.950   268554.107    ops/s
i.g.j.b.BoonBenchmark.menu                    thrpt   8         5    1  1959464.230   505004.028    ops/s
Boon over 2x faster!
Winner overall for byte[]. Boon KILLS IT! Sweep!

InputStream

Benchmark                                                Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.inputStream.BoonBenchmark.actionLabel             thrpt   8         5    1   168598.707    10702.291    ops/s
i.g.j.inputStream.JacksonObjectBenchmark.actionLabel    thrpt   8         5    1   165700.530     7939.486    ops/s
Boon barely wins

i.g.j.inputStream.BoonBenchmark.citmCatalog             thrpt   8         5    1      555.373       50.952    ops/s
i.g.j.inputStream.JacksonObjectBenchmark.citmCatalog    thrpt   8         5    1      285.610       66.244    ops/s
Boon wins by 2x

i.g.j.inputStream.BoonBenchmark.medium                  thrpt   8         5    1   159105.320    19057.916    ops/s
i.g.j.inputStream.JacksonObjectBenchmark.medium         thrpt   8         5    1   122754.690   130516.150    ops/s
Boon wins

i.g.j.inputStream.JacksonObjectBenchmark.menu           thrpt   8         5    1   252556.270   179084.546    ops/s
i.g.j.inputStream.BoonBenchmark.menu                    thrpt   8         5    1   184977.057     5153.660    ops/s
Jackson wins


i.g.j.inputStream.JacksonObjectBenchmark.sgml           thrpt   8         5    1   193714.667     3526.321    ops/s
i.g.j.inputStream.BoonBenchmark.sgml                    thrpt   8         5    1   180970.150     3499.859    ops/s
Jackson barely wins

i.g.j.inputStream.BoonBenchmark.webxml                  thrpt   8         5    1   132207.987   110279.994    ops/s
i.g.j.inputStream.JacksonObjectBenchmark.webxml         thrpt   8         5    1    87252.977    16961.356    ops/s
Boon wins by a really good margin!

i.g.j.inputStream.BoonBenchmark.widget                  thrpt   8         5    1   178216.637    21779.520    ops/s
i.g.j.inputStream.JacksonObjectBenchmark.widget         thrpt   8         5    1   171787.453    28138.131    ops/s
Boon wins
Boon wins nearly all, but Jackson wins a few here. GSON also does well at inputStream. Winner overall for inputStream. Boon!

Reader

Benchmark                             Mode Thr     Count  Sec         Mean   Mean error    Units
Benchmark                                      Mode Thr     Count  Sec         Mean   Mean error    Units

i.g.j.r.BoonBenchmark.actionLabel             thrpt   8         5    1   186001.097    18425.520    ops/s
i.g.j.r.JacksonObjectBenchmark.actionLabel    thrpt   8         5    1   163270.073     3730.813    ops/s
Boon wins!


i.g.j.r.BoonBenchmark.citmCatalog             thrpt   8         5    1      530.150      108.657    ops/s
i.g.j.r.JacksonObjectBenchmark.citmCatalog    thrpt   8         5    1      226.990       81.640    ops/s
Boon wins by a large margin!     Close to 2x

i.g.j.r.BoonBenchmark.medium                  thrpt   8         5    1   136242.553     4719.231    ops/s
i.g.j.r.JacksonObjectBenchmark.medium         thrpt   8         5    1   105882.313     3083.148    ops/s
Boon wins by 30%!


i.g.j.r.BoonBenchmark.menu                    thrpt   8         5    1   145418.360    19145.101    ops/s
i.g.j.r.JacksonObjectBenchmark.menu           thrpt   8         5    1   134975.063     7718.413    ops/s
Boon wins by a tad!

i.g.j.r.BoonBenchmark.sgml                    thrpt   8         5    1   128216.103   141559.091    ops/s
i.g.j.r.JacksonObjectBenchmark.sgml           thrpt   8         5    1   140934.190   123224.172    ops/s
Jackson wins!

i.g.j.r.JacksonObjectBenchmark.small          thrpt   8         5    1   145166.813     3960.731    ops/s
i.g.j.r.BoonBenchmark.small                   thrpt   8         5    1   145121.580    19487.609    ops/s
Almost a tie, but Jackson wins.


i.g.j.r.BoonBenchmark.webxml                  thrpt   8         5    1   116019.730    10943.316    ops/s
i.g.j.r.JacksonObjectBenchmark.webxml         thrpt   8         5    1    71660.963    43656.284    ops/s
Boon wins by a large margin about 35%.

i.g.j.r.BoonBenchmark.widget                  thrpt   8         5    1   143853.053    11396.247    ops/s
i.g.j.r.JacksonObjectBenchmark.widget         thrpt   8         5    1   119811.283    14264.563    ops/s
Boon wins by a large margin about 30%
In two instances Jackson barely beats boon. In one instance Jackson wins by 15%. Boon wins by 200%, 35%, 30% and 30%. Then there are a few smaller wins for Boon.
Winner overall for reader. Boon!

Object Serialization

Jackson
Benchmark                                    Mode Thr     Count  Sec         Mean   Mean error    Units
i.g.j.s.BoonSerializer.roundTriper          thrpt   8         5    1   214115.270    64366.819    ops/s
i.g.j.s.JacksonSerializer.roundTriper       thrpt   8         5    1    96239.373    91586.021    ops/s
Boon over 2x faster!


i.g.j.s.BoonSerializer.serializeSmall       thrpt   8         5    1   692168.577    70292.894    ops/s
i.g.j.s.JacksonSerializer.serializeSmall    thrpt   8         5    1   436992.523    68051.334    ops/s
Boon is substantially faster!
Boon wins the object serialization battle.

Boon is part of QBit. QBit uses Boon. QBit is a microservice lib featuring REST, HTTP, JSON and WebSocket and an event bus that can be easily integrated in with Kafka, STOMP, etc. QBit picks up where Boon left off.

Learn more about QBit and microservices:


  • [Detailed Tutorial] QBit microservice example
  • [Doc] Queue Callbacks for QBit queue based services
  • [Quick Start] Building a simple Rest web microservice server with QBit
  • [Quick Start] Building a TODO web microservice client with QBit
  • [Quick Start] Building a TODO web microservice server with QBit
  • [Quick Start] Building boon for the QBit microservice engine
  • [Quick Start] Building QBit the microservice lib for Java
  • [Rough Cut] Delivering up Single Page Applications from QBit Java JSON Microservice lib
  • [Rough Cut] Working with event bus for QBit the microservice engine
  • [Rough Cut] Working with inproc MicroServices
  • [Rough Cut] Working with private event bus for inproc microservices
  • [Rough Cut] Working with strongly typed event bus proxies for QBit Java Microservice lib
  • [Rough Cut] Working with System Manager for QBit Mircoservice lib
  • [Z Notebook] More benchmarking internal
  • [Z Notebook] Performance testing for REST
  • [Z Notebook] Roadmap
  • Home
  • Introduction to QBit
  • Local Service Proxies
  • QBit Boon New Wave of JSON HTTP and Websocket
  • QBit Docs
  • Kafka and Cassandra support, training for AWS EC2 Cassandra 3.0 Training