# JSON Support

Jersey JSON support comes as a set of JAX-RS &jaxrs.ext.MessageBodyReader; and &jaxrs.ext.MessageBodyWriter; providers distributed with jersey-json module. These providers enable using three basic approaches when working with JSON format:

- POJO support

- JAXB based JSON support

- Low-level, JSONObject/JSONArray based JSON support

The first method is pretty generic and allows you to map any Java Object to JSON and vice versa. The other two approaches limit you in Java types your resource methods could produce and/or consume. JAXB based approach could be taken if you want to utilize certain JAXB features. The last, low-level, approach gives you the best fine-grained control over the outcoming JSON data format.

## POJO support

POJO suppport represents the easiest way to convert your Java Objects to JSON and back. It is based on the Jackson library.

To use this approach, you will need to turn the JSONConfiguration.FEATURE_POJO_MAPPING feature on. This could be done in `web.xml` using the following servlet init parameter:

POJO JSON support web.xml configuration

            <init-param>
                <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
                <param-value>true</param-value>
            </init-param>

The following snippet shows how to use the POJO mapping feature on the client side:

POJO JSON support client configuration

      ClientConfig clientConfig = new DefaultClientConfig();
      clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
      Client client = Client.create(clientConfig);

Jackson JSON processor could be futher controlled via providing custom Jackson ObjectMapper instance. This could be handy if you need to redefine the default Jackson behaviour and to fine-tune how your JSON data structures look like. Detailed description of all Jackson features is out of scope of this guide. The example bellow gives you a hint on how to wire your ObjectMapper instance into your Jersey application.

Download https://maven.java.net/service/local/artifact/maven/redirect?r=&repository;&g=com.sun.jersey.samples&a=jacksonjsonprovider&v=&version;&c=project&e=zip to get a complete example using POJO based JSON support.

## JAXB Based JSON support

Taking this approach will save you a lot of time, if you want to easily produce/consume both JSON and XML data format. Because even then you will still be able to use a unified Java model. Another advantage is simplicity of working with such a model, as JAXB leverages annotated POJOs and these could be handled as simple Java beans.

A disadvantage of JAXB based approach could be if you need to work with a very specific JSON format. Then it could be difficult to find a proper way to get such a format produced and consumed. This is a reason why a lot of configuration options are provided, so that you can control how things get serialized out and deserialized back.

Following is a very simple example of how a JAXB bean could look like.

Simple JAXB bean implementation

    @XmlRootElement
    public class MyJaxbBean {
      public String name;
      public int age;

      public MyJaxbBean() {} // JAXB needs this

      public MyJaxbBean(String name, int age) {
        this.name = name;
        this.age = age;
      }
    }

Using the above JAXB bean for producing JSON data format from you resource method, is then as simple as:

JAXB bean used to generate JSON representation

    @GET @Produces("application/json")
    public MyJaxbBean getMyBean() {
       return new MyJaxbBean("Agamemnon", 32);
    }

Notice, that JSON specific mime type is specified in @Produces annotation, and the method returns an instance of MyJaxbBean, which JAXB is able to process. Resulting JSON in this case would look like:

        {"name":"Agamemnon", "age":"32"}

### Configuration Options

JAXB itself enables you to control output JSON format to certain extent. Specifically renaming and ommiting items is easy to do directly using JAXB annotations. E.g. the following example depicts changes in the above mentioned MyJaxbBean that will result in `{"king":"Agamemnon"}` JSON output.

Tweaking JSON format using JAXB

    @XmlRootElement
    public class MyJaxbBean {

        @XmlElement(name="king")
        public String name;

        @XmlTransient
        public int age;

        // several lines removed
    }

To achieve more important JSON format changes, you will need to configure Jersey JSON procesor itself. Various configuration options could be set on an JSONConfiguration instance. The instance could be then further used to create a JSONConfigurated JSONJAXBContext, which serves as a main configuration point in this area. To pass your specialized JSONJAXBContext to Jersey, you will finally need to implement a JAXBContext &jaxrs.ext.ContextResolver;:

An example of a JAXBContext resolver implementation

    @Provider
    public class JAXBContextResolver implements ContextResolver<JAXBContext> {

        private JAXBContext context;
        private Class[] types = {MyJaxbBean.class};

        public JAXBContextResolver() throws Exception {
            this.context =
    	  new JSONJAXBContext(
    	    JSONConfiguration.natural().build(), types);
        }

        public JAXBContext getContext(Class<?> objectType) {
            for (Class type : types) {
                if (type == objectType) {
                    return context;
                }
            }
            return null;
        }
    }

Creation of our specialized JAXBContext

Final JSON format is given by this JSONConfiguration instance

### JSON Notations

JSONConfiguration allows you to use four various JSON notations. Each of these notations serializes JSON in a different way. Following is a list of supported notations:

- MAPPED (default notation)

- NATURAL

- JETTISON_MAPPED

- BADGERFISH

Individual notations and their further configuration options are described bellow. Rather then explaining rules for mapping XML constructs into JSON, the notations will be described using a simple example. Following are JAXB beans, which will be used.

JAXB beans for JSON supported notations description, simple address bean

    @XmlRootElement
    public class Address {
        public String street;
        public String town;

        public Address(){}

        public Address(String street, String town) {
            this.street = street;
            this.town = town;
        }
    }

JAXB beans for JSON supported notations description, contact bean

    @XmlRootElement
    public class Contact {

        public int id;
        public String name;
        public List<Address> addresses;

        public Contact() {};

        public Contact(int id, String name, List<Address> addresses) {
            this.name = name;
            this.id = id;
            this.addresses =
    	        (addresses != null) ? new LinkedList<Address>(addresses) : null;
        }
    }

Following text will be mainly working with a contact bean initialized with:

JAXB beans for JSON supported notations description, initialization

    final Address[] addresses = {new Address("Long Street 1", "Short Village")};
    Contact contact = new Contact(2, "Bob", Arrays.asList(addresses));

I.e. contact bean with `id=2`, `name="Bob"` containing a single address (`street="Long Street 1"`, `town="Short Village"`).

All bellow described configuration options are documented also in apidocs at

#### Mapped notation

`JSONConfiguration` based on `mapped` notation could be build with

    JSONConfiguration.mapped().build()

for usage in a `JAXBContext` resolver, . Then a contact bean initialized with , will be serialized as

JSON expression produced using `mapped` notation

    { "id":"2"
     ,"name":"Bob"
     ,"addresses":{"street":"Long Street 1"
                        ,"town":"Short Village"}}

The JSON representation seems fine, and will be working flawlessly with Java based Jersey client API.

However, at least one issue might appear once you start using it with a JavaScript based client. The information, that `addresses` item represents an array, is being lost for every single element array. If you added another address bean to the contact,

    contact.addresses.add(new Address("Short Street 1000", "Long Village"));

, you would get

    { "id":"2"
     ,"name":"Bob"
     ,"addresses":[{"street":"Long Street 1","town":"Short Village"}
                  ,{"street":"Short Street 1000","town":"Long Village"}]}

Both representations are correct, but you will not be able to consume them using a single JavaScript client, because to access `"Short Village"` value, you will write `addresses.town` in one case and `addresses[0].town` in the other. To fix this issue, you need to instruct the JSON processor, what items need to be treated as arrays by setting an optional property, `arrays`, on your `JSONConfiguration` object. For our case, you would do it with

Force arrays in `mapped` JSON notation

    JSONConfiguration.mapped().arrays("addresses").build()

You can use multiple string values in the `arrays` method call, in case you are dealing with more than one array item in your beans. Similar mechanism (one or more argument values) applies also for all below desribed options.

Another issue might be, that number value, `2`, for `id` item gets written as a string, `"2"`. To avoid this, you can use another optional property on `JSONConfiguration` called `nonStrings`.

Force non-string values in `mapped` JSON notation

    JSONConfiguration.mapped().arrays("addresses").nonStrings("id").build()

It might happen you use XML attributes in your JAXB beans. In `mapped` JSON notation, these attribute names are prefixed with `@` character. If `id` was an attribute, it´s definition would look like:

      ...
      @XmlAttribute
      public int id;
      ...

and then you would get

    {"@id":"2" ...

at the JSON output. In case, you want to get rid of the `@` prefix, you can take advantage of another configuration option of `JSONConfiguration`, called `attributeAsElement`. Usage is similar to previous options.

XML attributes as XML elements in `mapped` JSON notation

    JSONConfiguration.mapped().attributeAsElement("id").build()

`Mapped` JSON notation was designed to produce the simplest possible JSON expression out of JAXB beans. While in XML, you must always have a root tag to start a XML document with, there is no such a constraint in JSON. If you wanted to be strict, you might have wanted to keep a XML root tag equivalent generated in your JSON. If that is the case, another configuration option is available for you, which is called `rootUnwrapping`. You can use it as follows:

Keep XML root tag equivalent in JSON `mapped` JSON notation

    JSONConfiguration.mapped().rootUnwrapping(false).build()

and get the following JSON for our `Contact` bean:

XML root tag equivalent kept in JSON using `mapped` notation

    {"contact":{ "id":"2"
     ,"name":"Bob"
     ,"addresses":{"street":"Long Street 1"
                        ,"town":"Short Village"}}}

`rootUnwrapping` option is set to `true` by default. You should switch it to `false` if you use inheritance at your JAXB beans. Then JAXB might try to encode type information into root element names, and by stripping these elements off, you could break unmarshalling.

In version 1.1.1-ea, XML namespace support was added to the MAPPED JSON notation. There is of course no such thing as XML namespaces in JSON, but when working from JAXB, XML infoset is used as an intermediary format. And then when various XML namespaces are used, ceratin information related to the concrete namespaces is needed even in JSON data, so that the JSON procesor could correctly unmarshal JSON to XML and JAXB. To make it short, the XML namespace support means, you should be able to use the very same JAXB beans for XML and JSON even if XML namespaces are involved.

Namespace mapping definition is similar to

XML namespace to JSON mapping configuration for `mapped` notation

            Map<String,String> ns2json = new HashMap<String, String>();
            ns2json.put("http://example.com", "example");
            context = new JSONJAXBContext(
    	      JSONConfiguration.mapped()
    	           .xml2JsonNs(ns2json).build(), types);

Dot character (.) will be used by default as a namespace separator in the JSON identifiers. E.g. for the above mentioned `example` namespace and tag `T`, `"example.T"` JSON identifier will be generated. To change this default behaviour, you can use the `nsSeparator` method on the mapped JSONConfiguration builder: `JSONConfiguration.mapped().xml2JsonNs(ns2json).nsSeparator(':').build()`. Then you will get `"example:T"` instead of `"example.T"` generated. This option should be used carefully, as the Jersey framework does not even try to check conflicts between the user selected separator character and the tag and/or namespace names.

#### Natural notation

After using `mapped` JSON notation for a while, it was apparent, that a need to configure all the various things manually could be a bit problematic. To avoid the manual work, a new, `natural`, JSON notation was introduced in Jersey version 1.0.2. With `natural` notation, Jersey will automatically figure out how individual items need to be processed, so that you do not need to do any kind of manual configuration. Java arrays and lists are mapped into JSON arrays, even for single-element cases. Java numbers and booleans are correctly mapped into JSON numbers and booleans, and you do not need to bother with XML attributes, as in JSON, they keep the original names. So without any additional configuration, just using

    JSONConfiguration.natural().build()

for configuring your `JAXBContext`, you will get the following JSON for the bean initialized at :

JSON expression produced using `natural` notation

    { "id":2
     ,"name":"Bob"
     ,"addresses":[{"street":"Long Street 1"
                         ,"town":"Short Village"}]}

You might notice, that the single element array `addresses` remains an array, and also the non-string `id` value is not limited with double quotes, as `natural` notation automatically detects these things.

To support cases, when you use inheritance for your JAXB beans, an option was introduced to the `natural` JSON configuration builder to forbid XML root element stripping. The option looks pretty same as at the default `mapped` notation case ().

Keep XML root tag equivalent in JSON `natural` JSON notation

    JSONConfiguration.natural().rootUnwrapping(false).build()

#### Jettison mapped notation

Next two notations are based on project Jettison. You might want to use one of these notations, when working with more complex XML documents. Namely when you deal with multiple XML namespaces in your JAXB beans.

Jettison based `mapped` notation could be configured using:

    JSONConfiguration.mappedJettison().build()

If nothing else is configured, you will get similar JSON output as for the default, `mapped`, notation:

JSON expression produced using Jettison based `mapped` notation

    { "contact:{"id":2
                  ,"name":"Bob"
                  ,"addresses":{"street":"Long Street 1"
                                     ,"town":"Short Village"}}

The only difference is, your numbers and booleans will not be converted into strings, but you have no option for forcing arrays remain arrays in single-element case. Also the JSON object, representing XML root tag is being produced.

If you need to deal with various XML namespaces, however, you will find Jettison `mapped` notation pretty useful. Lets define a particular namespace for `id` item:

      ...
      @XmlElement(namespace="http://example.com")
      public int id;
      ...

Then you simply confgure a mapping from XML namespace into JSON prefix as follows:

XML namespace to JSON mapping configuration for Jettison based `mapped` notation

            Map<String,String> ns2json = new HashMap<String, String>();
            ns2json.put("http://example.com", "example");
            context = new JSONJAXBContext(
    	      JSONConfiguration.mappedJettison()
    	           .xml2JsonNs(ns2json).build(), types);

Resulting JSON will look like in the example bellow.

JSON expression with XML namespaces mapped into JSON

    { "contact:{"example.id":2
                  ,"name":"Bob"
                  ,"addresses":{"street":"Long Street 1"
                                     ,"town":"Short Village"}}

Please note, that `id` item became `example.id` based on the XML namespace mapping. If you have more XML namespaces in your XML, you will need to configure appropriate mapping for all of them

#### Badgerfish notation

Badgerfish notation is the other notation based on Jettison. From JSON and JavaScript perspective, this notation is definitely the worst readable one. You will probably not want to use it, unless you need to make sure your JAXB beans could be flawlessly written and read back to and from JSON, without bothering with any formatting configuration, namespaces, etc.

`JSONConfiguration` instance using `badgerfish` notation could be built with

    JSONConfiguration.badgerFish().build()

and the output JSON for will be as follows.

JSON expression produced using `badgerfish` notation

    {"contact":{"id":{"$":"2"}
                  ,"name":{"$":"Bob"}
                  ,"addresses":{"street":{"$":"Long Street 1"}
                                     ,"town":{"$":"Short Village"}}}}

### Examples

Download https://maven.java.net/service/local/artifact/maven/redirect?r=&repository;&g=com.sun.jersey.samples&a=json-from-jaxb&v=&version;&c=project&e=zip or https://maven.java.net/service/local/artifact/maven/redirect?r=&repository;&g=com.sun.jersey.samples&a=jmaki-backend&v=&version;&c=project&e=zip to get a more complex example using JAXB based JSON support.

## Low-Level JSON support

Using this approach means you will be using JSONObject and/or JSONArray classes for your data representations. These classes are actually taken from Jettison project, but conform to the description provided at http://www.json.org/java/index.html.

The biggest advantage here is, that you will gain full control over the JSON format produced and consumed. On the other hand, dealing with your data model objects will probably be a bit more complex, than when taking the JAXB based approach. Differencies are depicted at the following code snipets.

JAXB bean creation

    MyJaxbBean myBean = new MyJaxbBean("Agamemnon", 32);

Above you construct a simple JAXB bean, which could be written in JSON as `{"name":"Agamemnon", "age":32}`

Now to build an equivalent JSONObject (in terms of resulting JSON expression), you would need several more lines of code.

Constructing a JSONObject

    JSONObject myObject = new JSONObject();
    myObject.JSONObject myObject = new JSONObject();
    try {
      myObject.put("name", "Agamemnon");
      myObject.put("age", 32);
    } catch (JSONException ex) {
      LOGGER.log(Level.SEVERE, "Error ...", ex);
    }

### Examples

Download https://maven.java.net/service/local/artifact/maven/redirect?r=&repository;&g=com.sun.jersey.samples&a=bookmark&v=&version;&c=project&e=zip to get a more complex example using low-level JSON support.