The Source for Java Technology Collaboration
User: Password:



Arun Gupta

Arun Gupta's Blog

TOTD #8: Generating JSON using JAXB annotations in Jersey

Posted by arungupta on September 10, 2007 at 06:11 AM | Comments (4)

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


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • There is a mistake I believe here in alice..

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

    Otherwise, a great tutorial and a great technology.

    Posted by: ivan_memruk on September 10, 2007 at 10:46 PM

  • Glad you liked it. It seems you are talking about 4th alice. "this" is implicit so wondering which of these you think is a mistake.

    Posted by: arungupta on September 10, 2007 at 11:14 PM

  • talking about the first alice. the constructor name should be alice() not States(), or I am missing something.

    Posted by: ivan_memruk on September 11, 2007 at 03:41 AM

  • ah I see, now fixed, thanks!

    Posted by: arungupta on September 11, 2007 at 05:56 AM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds