Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

JSON Overview

JSON is a textual data format for data exchange. JSON stands for Javascript Object Notation and, as the name implies, it is itself Javascript. Here is a small sample:

Code Block

{
  "customer" : {
    "name" : "Jane Doe",
    "company" : "Acme Enterprises"
}

One of the advantages of JSON is that is very easy for Javascript developers to use - it simply needs to be evaluated and it becomse javscript objects. For information on this see the JSON website.

JSON is supported in CXF through support for CXF can be enabled at a per endpoint level using Jettison. Jettison is a StAX implementation that reads and writes JSON. Jettison intercept calls to read/write XML and instead read/writes JSON.

JSON/XML Conventions

To understand how to create a JSON service, you first need to understand how your XML structures will be converted into the JSON format. It does this by providing different ways to map XML to JSON. These are called conventions.

TODO:

JSON does not have many concepts found in XML such as namespaces, attributes or entity references. Because of this we must adopt conventions on how to convert between the two.

Jettison supports two conventions currently. These are explained in more detail in the Jettison user's guide, but a quick summary of each follows.
1. The "mapped" convention. In this convention namespaces are mapped to json prefixes. For instance, if you have a namespace "http://acme.com" you could map it to the "acme" prefix. This means that the element <customer xmlns="http://acme.com"> would be mapped to the "acme.customer" JSON tag.
2. The BadgerFish convention. This convention provides a mapping of the full XML infoset to JSON. Attributes are represented with an @ sign - i.e. "@attributeName" : "value". Textual data is represented with the "$" as the tag. Example:

Code Block

{ "customer" : { "name" : { "$" : "Jane Doe" } } }

Configuring Jettison

Jettison is configured by setting properties on your service's endpoint. Depending on which way you create your service, this can be done slightly differently.

Using ServerFactoryBeans

This example shows how to set up Jettison using a ServerFactoryBean, such as the JaxWsServerFactoryBean. First you must create a properties HashMap and set the StAX XMLInputFactory and XMLOutputFactory:

Code Block

Map<String,Object> properties = new HashMap<String,Object>();

// Create a mapping between the XML namespaces and the JSON prefixes.
// The JSON prefix can be "" to specify that you don't want any prefix.
HashMap<String, String> nstojns = new HashMap<String,String>();
nstojns.put("http://customer.acme.com", "acme");

MappedXMLInputFactory xif = new MappedXMLInputFactory(nstojns);
properties.put(XMLInputFactory.class.getName(), xif);

MappedXMLOutputFactory xof = new MappedXMLOutputFactory(nstojns);
properties.put(XMLOutputFactory.class.getName(), xof);

You must also tell CXF which Content-Type you wish to serve:

Code Block

// Tell CXF to use a different Content-Type for the JSON endpoint
// This should probably be application/json, but text/plain allows
// us to view easily in a web browser.
properties.put("Content-Type", "text/plain");

Last, you'll want to actually create your service:

Code Block

// Build up the server factory bean
JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
sf.setServiceClass(CustomerService.class);
// Use the HTTP Binding which understands the Java Rest Annotations
sf.setBindingFactory(new HttpBindingInfoFactoryBean());
sf.setAddress("http://localhost:8080/json");
sf.setServiceBean(new CustomerServiceImpl());

sf.setProperties(properties);

sf.create();

...