Skip to main content

TOTD #8: Generating JSON using JAXB annotations in Jersey

Posted by arungupta on September 10, 2007 at 6:11 AM PDT

Jersey provides a
pluggable
type system
for the encoding/decoding of a Java type to/from an entity of an
HTTP response/request.
JSON
support
was added in Jersey using the
BadgerFish
convention for encoding/decoding
JAXB beans to/from JSON. A new
sample was also added in the
recently released
0.2.1
that demonstrates this concept.

This TOTD provides provides a trivial sample (using the snippets shown on
BadgerFish) that will allow you to
experiment with this feature in Jersey. This sample consists of a Resource,
Server and "build.xml" to build, deploy, run the server and invoke
the endpoint.

Here is the code for the REST resource:

import javax.ws.rs.HttpMethod;

import javax.ws.rs.ProduceMime;

import javax.ws.rs.UriTemplate;



@UriTemplate("/helloworld")

public class HelloWorldResource {



  @HttpMethod

  @ProduceMime("application/xml")

  @UriTemplate("/xml")

  public States getXML() {

    return new alice();

  }



  @HttpMethod

  @ProduceMime("application/json")

  @UriTemplate("/json")

  public States getJSON() {

    return new alice();

  }

}

This resource is published on two URIs - one using XML (/xml)
and the other using JSON (/json) representation. Here is the code
to start the server:

import com.sun.net.httpserver.HttpHandler;

import com.sun.net.httpserver.HttpServer;

import com.sun.ws.rest.api.container.ContainerFactory;

import java.io.IOException;

import java.net.InetSocketAddress;



public class HelloWorld {

  public static void main(String[] args) throws IOException {

    HttpHandler handler = ContainerFactory.createContainer(

      HttpHandler.class,

      HelloWorldResource.class);



    HttpServer server = HttpServer.create(new
InetSocketAddress(9998), 0);

    server.createContext("/", handler);

    server.setExecutor(null);

    server.start();



    System.out.println("Server running");

    System.out.println("Visit: http://localhost:9998/helloworld");

    System.out.println("Hit return to stop...");

    System.in.read();

    System.out.println("Stopping server");

    server.stop(0);

    System.out.println("Server stopped");

  }

}

This is a very standard code that is available in all the bundled samples.
And here is the "build.xml":

<project name="json" default="default" basedir=".">

  <property name="jersey.home" value="c:\jersey-0.2.1-ea"/>

  <path id="jersey.classpath">

    <fileset dir="${jersey.home}\lib" includes="*.jar"/>

  </path>

  <property name="build.dir" value="build"/>

  <property name="src.dir" value="src"/>



  <target name="init">

    <mkdir dir="${build.dir}"/>

  </target>



  <target name="build" depends="init">

    <javac srcdir="${src.dir}" destdir="${build.dir}"
includes="**/*.java">

      <classpath refid="jersey.classpath"/>

    </javac>

  </target>



  <target name="run" depends="build">

    <java classname="samples.HelloWorld" fork="true">

      <classpath>

        <path refid="jersey.classpath"/>

        <pathelement location="${build.dir}"/>

      </classpath>

    </java>

  </target>



  <target name="get-json">

    <get src="http://localhost:9998/helloworld/json" dest="out.json"/>

  </target>



  <target name="get-xml">

    <get src="http://localhost:9998/helloworld/xml" dest="out.xml"/>

  </target>



  <target name="clean">

    <delete quiet="true" dir="${build.dir}"/>

  </target>

</project>

Make sure to set the value of "jersey.home" property correctly
in this file. And now the JAXB bean and corresponding XML and JSON
representation:

JAXB Bean XML representation JSON representation
@javax.xml.bind.annotation.XmlRootElement

public class alice {



 
@javax.xml.bind.annotation.XmlValue

 
protected String value;



 
public alice() { this.value = "bob"
}

 
public String getValue() {
return value;
}

}
<alice>bob</alice> {"alice":{"$":"bob"}}
@javax.xml.bind.annotation.XmlRootElement

public class alice {



  @javax.xml.bind.annotation.XmlElement

  protected String bob;



  @javax.xml.bind.annotation.XmlElement

  protected String david;



  public alice() {

    bob = "charlie";

    david = "edgar";

  }



  public String getBob() { return bob; }

  public String getDavid() { return david; }

}
<alice>

  <bob>charlie</bob>

  <david>edgar</david>

</alice>
{"alice":{"bob":{"$":"charlie"},"david":{"$":"edgar"}}}
@javax.xml.bind.annotation.XmlRootElement

public class alice {

  @javax.xml.bind.annotation.XmlValue

  protected String value;



  @javax.xml.bind.annotation.XmlAttribute

  protected String charlie;



  public alice() {

    value = "bob";

    charlie = "david";

  }



  public String getValue() { return value; }

  public String getCharlie() { return charlie; }

}
<alice charlie="david">

  bob

</alice>
{"alice":{"@charlie":"david","$":"bob"}}
@javax.xml.bind.annotation.XmlRootElement(namespace="http://some-namespace")

public class alice {

  @javax.xml.bind.annotation.XmlValue

  protected String value;



  public alice() { value = "bob"; }



  public String getValue() { return value; }

}
<alice xmlns="http://some

-namespace">

  bob

</alice>
{"alice":{"@xmlns":{"$":"http:\/\/some-namespace"},"$":"bob"}}
@javax.xml.bind.annotation.XmlRootElement

public class alice {

  @javax.xml.bind.annotation.XmlElement

  protected java.util.List<String> bob;



  public alice() {

    bob = new java.util.ArrayList<String>();

    bob.add("charlie");

    bob.add("david");

  }



  public java.util.List<String> getBob() { return bob; }

}
<alice>

  <bob>charlie</bob>

  <bob>david</bob>

</alice>
{"alice":{"bob":[{"$":"charlie"},{"$":"david"}]}}

JSON representation can always be constructed using the JSON APIs as shown
below and by adding the method to "HelloWorldResource":

import org.codehaus.jettison.json.*;
@HttpMethod("GET") 

@ProduceMime("application/json")

@UriTemplate("/json2")

public JSONObject getJSONMessage() throws JSONException {

  JSONObject object = new JSONObject();

  JSONObject content = new JSONObject();

  content.put("$", "bob");

  object.put("alice", content);



  return object;

}

JAX-WS also supports JSON as a

pluggable encoding
.

Please leave suggestions on other TOTD that you'd like to see. A complete
archive is available here.

Technorati:
totd
jersey
json
jax-ws
REST
pluggableencoding
restful

Related Topics >>