{title:'Parsing into Generic Models', updated:'8.2.0'}

The Juneau parsers are not limited to parsing back into the original bean classes. If the bean classes are not available on the parsing side, the parser can also be used to parse into a generic model consisting of Maps, Collections, and primitive objects.

You can parse into any Map type (e.g. HashMap, TreeMap), but using {@link oaj.collections.JsonMap} is recommended since it has many convenience methods for converting values to various types. The same is true when parsing collections. You can use any Collection (e.g. HashSet, LinkedList) or array (e.g. Object[], String[], String[][]), but using {@link oaj.collections.JsonList} is recommended.

When the map or list type is not specified, or is the abstract Map, Collection, or List types, the parser will use JsonMap and JsonList by default.

For example, given the following 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 | } | ] | }

We can parse this into a generic JsonMap:

| // Parse JSON into a generic POJO model. | JsonMap map = JsonParser.DEFAULT.parse(json, JsonMap.class); | | // Convert it back to JSON. | String json = SimpleJsonSerializer.DEFAULT_READABLE.serialize(map);

What we end up with is the exact same output. Even the numbers and booleans are preserved because they are parsed into Number and Boolean objects when parsing into generic models.

| { | 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 | } | ] | }

Once parsed into a generic model, various convenience methods are provided on the JsonMap and JsonList classes to retrieve values:

| // Parse JSON into a generic POJO model. | JsonMap map = JsonParser.DEFAULT.parse(json, JsonMap.class); | | // Get some simple values. | String name = map.getString("name"); | int id = map.getInt("id"); | | // Get a value convertable from a String. | URI uri = map.get(URI.class, "uri"); | | // Get a value using a swap. | TemporalCalendarSwap swap = new TemporalCalendarSwap.IsoInstant(); | Calendar birthDate = map.get(swap, "birthDate"); | | // Get the addresses. | JsonList addresses = map.getList("addresses"); | | // Get the first address and convert it to a bean. | Address address = addresses.get(Address.class, 0);

As a general rule, parsing into beans is often more efficient than parsing into generic models. And working with beans is often less error prone than working with generic models.