Returning JSON response from JAXRS service

If your using JAXB for Java to XML conversion in the JAXRS service then changing it to support JSON becomes very easy, i wanted to try this option so built this application that can return response in application/xml and application/JSON type, you can download the sample application from here The sample service that i built in this case is ManageContact service, which supports call to return all the contacts, or contact for given contactId and also allows you to search a contact based on last name, in all these cases it returns a Contact object, i did mark the Contact.java class with @XmlRootElement annotation so that JAXBt knows that it is root element.

package com.javaworld.memcache;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Contact {
  private int contactId;
  private String firstName;
  private String lastName;
  private String email;
  
  public int getContactId() {
    return contactId;
  }
  public void setContactId(int contactId) {
    this.contactId = contactId;
  }
  public String getFirstName() {
    return firstName;
  }
  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }
  public String getLastName() {
    return lastName;
  }
  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
  public String getEmail() {
    return email;
  }
  public void setEmail(String email) {
    this.email = email;
  }
  @Override
  public String toString() {
    return "Contact [contactId=" + contactId + ", firstName=" + firstName
        + ", lastName=" + lastName + ", email=" + email + "]";
  }
}
Then i did create this ContactService class that uses JAXRS annotation to define what are the input types as well as what would be the content type of the output, my service looks like this

package com.javaworld.memcache;

import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

@Path("/contact")
public class ContactService {
  Logger logger = Logger.getLogger(ContactService.class);
  public ContactService(){
    logger.debug("Inside ContactService constructor");
    BasicConfigurator.configure();
  }

  @GET
  @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
  public List getContactList() {
    logger.debug("Entering ContactService.getContactList()");
    ContactDAO contactDAO = new ContactDAOImpl();
    List contactList = contactDAO.getContacts();
    logger.debug("Exiting ContactService.getContactList()");
    return contactList;
  }

  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
  public void insertContact(@FormParam("contactId") int contactId,
      @FormParam("firstName") String firstName,
      @FormParam("lastName") String lastName,
      @FormParam("email") String email) {
    Contact contact = new Contact();
    contact.setContactId(contactId);
    contact.setFirstName(firstName);
    contact.setLastName(lastName);
    contact.setEmail(email);
    ContactDAO contactDAO = new ContactDAOImpl();
    contactDAO.insertContact(contact);
  }

  @GET
  @Path("/{contactId}")
  @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
  public Contact getContact(@PathParam("contactId") int contactId) {
    ContactDAO contactDAO = new ContactDAOImpl();
    return contactDAO.getContact(contactId);

  }

  @DELETE
  @Path("/{contactId}")
  public void deleteContact(@PathParam("contactId") int contactId) {
    ContactDAO contactDAO = new ContactDAOImpl();
    contactDAO.deleteContact(contactId);
  }

  @PUT
  @Path("/{contactId}")
  @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  public void updateContact(@PathParam("contactId") int contactId,
      @FormParam("firstName") String firstName,
      @FormParam("lastName") String lastName,
      @FormParam("email") String email) {
    Contact contact = new Contact();
    contact.setContactId(contactId);
    contact.setFirstName(firstName);
    contact.setLastName(lastName);
    contact.setEmail(email);
    ContactDAO contactDAO = new ContactDAOImpl();
    contactDAO.updateContact(contact);
  }
  
  @GET
  @Path("/search")
  @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
  public List searchContact(@QueryParam("lastName") String lastName) {
    ContactDAO contactDAO = new ContactDAOImpl();
    return contactDAO.searchContact(lastName);

  }

}
My rest methods declare that they produce both MediaType.APPLICATION_JSON and MediaType.APPLICATION_XML content type. Now the next question would be which content type should it return when it gets request. So the rule is since MediaType.APPLICATION_JSON is first content type it becomes the default content type, so if you dont set content type it returns JSON, if you set content type to XML in request it returns XML like this Response when i did not set Accept header, so it returns JSON which is default content type
But if i want XML as response type i can set Accept header with value equal to application/xml and it returns XML
In Jersey configuration all you have to do to support JSON is make sure that you add jesey-json related jars in the classpath, which has JSON message writer which takes over when request has accept equal to JSON and returns JSON response

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.javaworld.memcache</groupId>
  <artifactId>ManageContact</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>ManageContact Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
      <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.4.2</version>

    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.4.2</version>

    </dependency>

    
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>3.4.0.GA</version>
    </dependency>
    <dependency>
      <groupId>org.apache.derby</groupId>
      <artifactId>derbyclient</artifactId>
      <version>10.7.1.1</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>commons-beanutils</groupId>
      <artifactId>commons-beanutils</artifactId>
      <version>1.8.0</version>
    </dependency>
    <dependency>
      <groupId>commons-beanutils</groupId>
      <artifactId>commons-beanutils</artifactId>
      <version>1.8.0</version>
    </dependency>
    <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-servlet</artifactId>
            <version>1.12</version>
        </dependency> 
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-json</artifactId>
            <version>1.12</version>
        </dependency> 
  </dependencies>
 
</project>

No comments: