Sunday Sep 09, 2007

TOTD #8: Generating JSON using JAXB annotations in Jersey

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

About

profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.


Java EE 7 Samples

Stay Connected

Search

Archives
« April 2015
SunMonTueWedThuFriSat
   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  
       
Today