{title:'Serializers and Parsers', updated:'9.0.0'}

One of the goals of Juneau was to make serialization as simple as possible. In a single line of code, you should be able to serialize and parse most POJOs. Despite this simplicity, Juneau provides lots of extensibility and configuration properties for tailoring how POJOs are serialized and parsed.

The built-in serializers in Juneau are fast, efficient, and highly configurable. They work by serializing POJOs directly to streams instead of using intermediate Document Object Model objects.

In most cases, you can serialize objects in one line of code by using one of the default serializers:

| // A simple bean | public class Person { | public String name = "John Smith"; | public int age = 21; | } | | // Serialize to JSON, XML, or HTML | Person person = new Person(); | | // Produces: | // "{\"name\":\"John Smith\",\"age\":21}" | String json = JsonSerializer. DEFAULT.serialize(person); | | // Produces: | // "{name:'John Smith',age:21}" | String json = Json5Serializer. DEFAULT.serialize(person); | | // Produces: | // <object> | // <name>John Smith</name> | // <age>21</age> | // </object> | String xml = XmlSerializer. DEFAULT.serialize(person); | | // Produces: | // <table> | // <tr><th>key</th><th>value</th></tr> | // <tr><td>name</td><td>John Smith</td></tr> | // <tr><td>age</td><td>21</td></tr> | // </table> | String html = HtmlSerializer. DEFAULT.serialize(person); | | // Produces: | // "(name='John Smith',age=21)" | String uon = UonSerializer. DEFAULT.serialize(person); | | // Produces: | // "name='John+Smith'&age=21" | String urlencoding = UrlEncodingSerializer. DEFAULT.serialize(person); | | // Produces: | // 82 A4 6E 61 6D 65 AA 4A 6F 68 6E 20 53 6D 69 74 68 A3 61 67 65 15 | byte[] bytes = MsgPackSerializer. DEFAULT.serialize(person);

In addition to the default serializers, customized serializers can be created using various built-in options:

| // Use one of the default serializers to serialize a POJO | String json = JsonSerializer. DEFAULT.serialize(someObject); | | // Create a custom serializer for lax syntax using single quote characters | JsonSerializer serializer = JsonSerializer. create().simple().sq().build(); | | // Clone an existing serializer and modify it to use single-quotes | JsonSerializer serializer = JsonSerializer. DEFAULT.copy().sq().build(); | | // Serialize a POJO to JSON | String json = serializer.serialize(someObject);

Default serialization support is provided for Java primitives, Maps, Collections, beans, and arrays. Extensible support for other data types such as Calendars, Dates, Iterators is available through the use of POJO swaps (described later).

Parsers work by parsing input directly into POJOs instead of having to create intermediate Document Object Models. This allows them to parse input with minimal object creation.

Like the serializers, you can often parse objects in one line of code by using one of the default parsers:

| // Use one of the predefined parsers. | Parser parser = JsonParser. DEFAULT; | | // Parse a JSON object as a bean. | String json = "{name:'John Smith',age:21}"; | Person person = parser.parse(json, Person. class); | | // Or parse it into a generic Map. | Map map = parser.parse(json, Map. class); | | // Parse a JSON string. | json = "'foobar'"; | String string = parser.parse(json, String. class); | | // Parse a JSON number as a Long or Float. | json = "123"; | Long _long = parser.parse(json, Long. class); | Float _float = parser.parse(json, Float. class); | | // Parse a JSON object as a HashMap<String,Person>. | json = "{a:{name:'John Smith',age:21},b:{name:'Joe Smith',age:42}}"; | Map<String,Person> map2 = parser.parse(json, HashMap. class, String. class, Person. class) | | // Parse a JSON object as a HashMap<String,LinkedList<Person>>. | json = "{a:[{name:'John Smith',age:21},{name:'Joe Smith',age:42}]}"; | Map<String,List<Person>> map3 = parser.parse(json, HashMap. class, String. class, | LinkedList. class, Person. class) | | // Parse a JSON array of integers as a Collection of Integers or int[] array. | json = "[1,2,3]"; | List<Integer> list = parser.parse(json, LinkedList. class, Integer. class); | int[] ints = parser.parse(json, int[].class);

The parsers can also be used to populating existing bean and collection objects:

| // Use one of the predefined parsers. | Parser parser = JsonParser. DEFAULT; | | // Populate the properties on an existing bean from a JSON object. | String json = "{name:'John Smith',age:21}"; | Person person = new Person(); | parser.parseIntoBean(json, person); | | // Populate an existing list from a JSON array of numbers. | json = "[1,2,3]"; | List<Integer> list = new LinkedList<Integer>(); | parser.parseIntoCollection(json, list, Integer. class); | | // Populate an existing map from a JSON object containing beans. | json = "{a:{name:'John Smith',age:21},b:{name:'Joe Smith',age:42}}"; | Map<String,Person> map = new TreeMap<String,Person>(); | parser.parseIntoMap(json, map, String. class, Person. class);

In the example above, we're parsing "lax" JSON (single quotes, unquoted attributes). The JSON parser can handle any valid JSON syntax (such as quoted or unquoted attributes, single or double quotes). It can also handle JSON fragments and embedded Javascript comments. Many of the JSON examples provided will use lax syntax which is easier to read since we don't have to deal with escapes.

- {@link oaj.examples.serializer.ImageSerializer} - Example of a custom serializer.
- {@link oaj.examples.parser.ImageParser} - Example of a custom parser.