juneau-marshall
Maven Dependency

<dependency> <groupId>org.apache.juneau</groupId> <artifactId>juneau-marshall</artifactId> <version>7.0.0</version> </dependency>

Java Library

juneau-marshall-7.0.0.jar

OSGi Module

org.apache.juneau.marshall_7.0.0.jar

The juneau-marshall library includes easy-to-use and highly customizable serializers and parsers based around a common API. They provide support for the following languages:

The default serializers can often be used to serialize POJOs in a single line of code:

// A simple bean public class Person { public String name = "John Smith"; public int age = 21; } Person p = new Person(); // Produces: // "{name:'John Smith',age:21}" String laxJson = JsonSerializer.DEFAULT_LAX.serialize(p); // Produces: // "{"name":"John Smith","age":21}" String strictJson = JsonSerializer.DEFAULT.serialize(p); // Produces: // <object> // <name>John Smith</name> // <age>21</age> // </object> String xml = XmlSerializer.DEFAULT_SIMPLE.serialize(p); // Produces: // <table> // <tr><td>name</td><td>John Smith</td></tr> // <tr><td>age</td><td>21</td></tr> // </table> String html = HtmlSerializer.DEFAULT.serialize(p); // Same as Html, but wraps it in HTML and BODY elements with page title/description/links: String htmlDoc = HtmlDocSerializer.DEFAULT.serialize(p); // Produces: // name='John+Smith'&age=21 String urlEncoding = UrlEncodingSerializer.DEFAULT.serialize(p); // Produces: // (name='John Smith',age=21) String uon = UonSerializer.DEFAULT.serialize(p); // Produces: // 82 A4 name AA 4A John Smith 68 A3 age 15 byte[] messagePack = MsgPackSerializer.DEFAULT.serialize(p);

Parsing back into POJOs is equally simple for any of the supported languages shown above. Language fragments are also supported.

JSON parsing shown here:

// Use one of the predefined parsers. ReaderParser parser = JsonParser.DEFAULT; // Parse a JSON object (creates a generic ObjectMap). String json = "{name:'John Smith',age:21}"; Map m1 = parser.parse(json, Map.class); // Parse a JSON string. json = "'foobar'"; String s2 = parser.parse(json, String.class); // Parse a JSON number as a Long or Float. json = "123"; Long l3 = parser.parse(json, Long.class); Float f3 = parser.parse(json, Float.class); // Parse a JSON object as a bean. json = "{name:'John Smith',age:21}"; Person p4 = parser.parse(json, Person.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> m5 = 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>> m6 = 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> l7 = parser.parse(json, LinkedList.class, Integer.class); int[] i7 = parser.parse(json, int[].class); // Parse arbitrary input into ObjectMap or ObjectList objects // (similar to JSONObject/JSONArray but generalized for all languages). json = "{name:'John Smith',age:21}"; ObjectMap m8a = parser.parse(json, ObjectMap.class); int age = m8a.getInt("age"); ObjectMap m8b = (ObjectMap)parser.parse(json, Object.class); // Equivalent. json = "[1,true,null]"; ObjectList l9a = parser.parse(json, ObjectList.class); boolean b = l9a.getBoolean(1); ObjectList l9b = (ObjectList)parser.parse(json, Object.class); // Equivalent.

Features


Serializers and parsers are builder-based. Build from scratch or clone existing instances. Lots of configuration options available for all the languages.

// Create a serializer from scratch using a builder. JsonSerializer serializer = JsonSerializer.create() .simple() // Simple mode .sq() // Use single quotes .pojoSwaps( // Swap unserializable classes with surrogate POJOs IteratorSwap.class, // Iterators swapped with lists ByteArrayBase64Swap.class, // byte[] swapped with base-64 encoded strings CalendarSwap.ISO8601DT.class // Calendars swapped with ISO8601-compliant strings ) .beanFilters(MyBeanFilter.class) // Control how bean properties are handled .timeZone(TimeZone.GMT) // For serializing Calendars .locale(Locale.JAPAN) // For timezone-specific serialization .sortCollections(true) // For locale-specific serialization .sortProperties(true) // Various behavior settings .trimNullProperties(true) .trimStrings(true) .methodVisibility(PROTECTED) // Control which fields/methods are serialized .beanDictionary( // Adds type variables for resolution during parsing MyBeanA.class, MyBeanB.class ) .debug(true) // Add debug output .build(); // Same as above, but using named properties. // This is how serializers and parsers are typically configured on REST servlets and clients. JsonSerializer serializer = JsonSerializer.create() .property(JSON_simpleMode, true) .property(SERIALIZER_quoteChar, '\'') .property(BEAN_pojoSwaps_add, IteratorSwap.class) .property(BEAN_pojoSwaps_add, ByteArrayBase64Swap.class) .property(BEAN_pojoSwaps_add, CalendarSwap.ISO8601DT.class) .property(BEAN_beanFilters_add, MyBeanFilter.class) .property(BEAN_timeZone, TimeZone.GMT) .property(BEAN_locale, Locale.JAPAN) .property(SERIALIZER_sortCollections, true) .property(BEAN_sortProperties, true) .property(SERIALIZER_trimNullProperties, true) .property(SERIALIZER_trimStrings, true) .property(BEAN_methodVisibility, PROTECTED) .property(BEAN_beanDictionary_add, MyBeanA.class) .property(BEAN_beanDictionary_add, MyBeanB.class) .property(BEAN_debug, true) .build(); // Clone an existing serializer and modify it to use single-quotes. JsonSerializer serializer = JsonSerializer.DEFAULT.builder() .sq() .build();




Many POJOs such as primitives, beans, collections, arrays, and classes with various known constructors and methods are serializable out-of-the-box. For other objects, "transforms" allow you to perform various mutations on them before serialization and after parsing.



UON (URL-Encoded Object Notation) allows JSON-like data structures (OBJECT, ARRAY, NUMBER, BOOLEAN, STRING, NULL) in HTTP constructs (query parameters, form parameters, headers, URL parts) without violating RFC2396. This allows POJOs to be converted directly into these HTTP constructs which is not possible in any other language such as JSON.

( id=1, name='John+Smith', uri=http://sample/addressBook/person/1, addressBookUri=http://sample/addressBook, birthDate=1946-08-12T00:00:00Z, addresses=@( ( uri=http://sample/addressBook/address/1, personUri=http://sample/addressBook/person/1, id=1, street='100+Main+Street', city=Anywhereville, state=NY, zip=12345, isCurrent=true ) ) )



Lots of shortcuts are provided throughout the API to simplify tasks, and the APIs are often useful for debugging and logging purposes as well...

// Create JSON strings from scratch using fluent-style code. String jsonObject = new ObjectMap().append("foo","bar").toString(); String jsonArray = new ObjectList().append("foo").append(123).append(null).toString(); // Create maps and beans directly from JSON. Map<String,Object> myMap = new ObjectMap("{foo:'bar'}"); List<Object> myList = new ObjectList("['foo',123,null]"); // Load a POJO from a JSON file. MyPojo myPojo = JsonParser.DEFAULT.parse(new File("myPojo.json")); // Serialize POJOs and ignore exceptions (great for logging) String json = JsonSerializer.DEFAULT_LAX.toString(myPojo); // Dump a POJO to the console. JsonSerializer.DEFAULT_LAX.println(myPojo); // Delayed serialization. // (e.g. don't serialize an object if it's not going to be logged). logger.log(FINE, "My POJO was: {0}", new StringObject(myPojo)); logger.log(FINE, "My POJO in XML was: {0}", new StringObject(XmlSerializer.DEFAULT, myPojo)); String message = new StringMessage("My POJO in {0}: {1}", "JSON", new StringObject(myPojo)).toString(); // Create a 'REST-like' wrapper around a POJO. // Allows you to manipulate POJO trees using URIs and GET/PUT/POST/DELETE commands. PojoRest pojoRest = new PojoRest(myPojo); pojoRest.get(String.class, "addressBook/0/name"); pojoRest.put("addressBook/0/name", "John Smith");




SerializerGroup and ParserGroup classes allow serializers and parsers to be retrieved by W3C-compliant HTTP Accept and Content-Type values:

// Construct a new serializer group with configuration parameters that get applied to all serializers. SerializerGroup sg = SerializerGroup.create() .append(JsonSerializer.class, UrlEncodingSerializer.class); .ws() // or .setUseWhitespace(true) or .property(SERIALIZER_useWhitespace, true) .pojoSwaps(CalendarSwap.ISO8601DT.class) // or .property(BEAN_pojoSwaps_add, CalendarSwap.ISO8601DT.class) .build(); // Find the appropriate serializer by Accept type and serialize our POJO to the specified writer. // Fully RFC2616 compliant. sg.getSerializer("text/invalid, text/json;q=0.8, text/*;q:0.6, *\/*;q=0.0") .serialize(myPersonObject, myWriter); // Construct a new parser group with configuration parameters that get applied to all parsers. ParserGroup pg = ParserGroup.create() .append(JsonParser.class, UrlEncodingParser.class); .pojoSwaps(CalendarSwap.ISO8601DT.class) // or .property(BEAN_pojoSwaps_add, CalendarSwap.ISO8601DT.class) .build(); Person p = pg.getParser("text/json").parse(myReader, Person.class);




juneau-marshall-rdf
Maven Dependency

<dependency> <groupId>org.apache.juneau</groupId> <artifactId>juneau-marshall-rdf</artifactId> <version>7.0.0</version> </dependency>

Java Library

juneau-marshall-rdf-7.0.0.jar

OSGi Module

org.apache.juneau.marshall.rdf_7.0.0.jar

The juneau-marshall-rdf library provides additional serializers and parsers for RDF. These rely on the Apache Jena library to provide support for the following languages:

The serializers and parsers work identically to those in juneau-marshall, but are packaged separately so that you don't need to pull in the Jena dependency unless you need it.

// A simple bean public class Person { public String name = "John Smith"; public int age = 21; } // Serialize a bean to JSON, XML, or HTML Person p = new Person(); // Produces: // <rdf:RDF // xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" // xmlns:jp="http://www.apache.org/juneaubp/" // xmlns:j="http://www.apache.org/juneau/"> // <rdf:Description> // <jp:name>John Smith</jp:name> // <jp:age>21</jp:age> // </rdf:Description> // </rdf:RDF> String rdfXml = RdfSerializer.DEFAULT_XMLABBREV.serialize(p); // Produces: // @prefix jp: <http://www.apache.org/juneaubp/> . // @prefix j: <http://www.apache.org/juneau/> . // [] jp:age "21" ; // jp:name "John Smith" . String rdfN3 = RdfSerializer.DEFAULT_N3.serialize(p); // Produces: // _:A3bf53c85X3aX157cf407e2dX3aXX2dX7ffd <http://www.apache.org/juneaubp/name> "John Smith" . // _:A3bf53c85X3aX157cf407e2dX3aXX2dX7ffd <http://www.apache.org/juneaubp/age> "21" . String rdfNTriple = RdfSerializer.DEFAULT_NTRIPLE.serialize(p);