Java REST Web Services with JAX-RS, JSON, and JAXB: Part Two

REST Web Services with JAX-RS, JSON, and JAXB: Part Two

This is the second article in my series on REST using Apache Wink. My previous article covered using JAX-RS (REST web services) using Apache Wink. This programming tutorial uses the same service that we built in part one to return complex types. These types include XML using JAXB and JSON using Jackson as the stream reader or stream writer.

Before we begin, consider refreshing your knowledge of some of the important terminologies and techniques for REST and web services, as showcased in part one of this series of starting JAX-RS/Rest web services using Apache Wink. Make sure you have setup the JAX-RS/REST project as described in the previous article before you go any further.

How to Return XML Using JAXB

The class, whose object has to be returned to the client, must first be annotated using the following annotations:

  • XMLRootElement: The root element of the xml that has to be returned at the class level.
  • XMLAttribute: An attribute of the root element that has to be returned.
  • XMLElement: An element contained within the root element.

We can do this using nesting to allow multiple levels of nested objects, which get returned to the invoker. Observe the code below:

 package me.sumithpuri.rest.vo;   
 import javax.xml.bind.annotation.XmlAttribute;   
 /**   
  * @author sumith_puri   
  *   
 */   
 @XmlRootElement(name="product")   
 public class Product {   
   long id;   
   String name;   
   @XmlAttribute   
   public long getId() {   
     return id;   
   }   
   public void setId(long id) {   
     this.id = id;   
   }   
   @XmlElement(name="name")   
   public String getName() {   
     return name;   
   }   
   public void setName(String name) {   
     this.name = name;   
   }   
   public String toString() {   
     String productStr="ID:" + this.id + ", NAME: " + this.name;   
     return productStr;   
   }   
 }   


The respective methods now need to be annotated to return XML using @Produces.

 @GET   
    @Path("/{id}")   
    @Produces(MediaType.APPLICATION_XML)   
    public Product getProductById(@PathParam(value="id") long id) {   
      Product product = persistenceManager.getProduct(id);   
      return product;   
    }   


We can access this method now using a REST Client:

  public void invokeJAXBGET(long id) {   
       System.out.println("Testing JAXB GET command....");      
       RestClient restClient = new RestClient(clientConfig);   
       Resource resource = restClient.resource(REST_WEB_SERVICE+"/"+id);   
       ClientResponse response=resource.accept(MediaType.APPLICATION_XML).get();   
       System.out.println("...JAXB GET command is successful");   
    }   


Next, open an Internet browser and navigate to: http://localhost:8080/products/rest/product/3.

  <product id="3">  
 <name>Sumith Puri</name>  
 </product>      

How to Return JSON Using Jackson

Jackson is an extension of JAXB used to return JSON from REST web services. It can be used as a mapper to convert from JAXB. To do so, we must first include the relevant Jackson JARs, as shown in the image below:

REST Web Services with Apache Wink

We also have to write an application class to register the mapper. Here is what that looks like in Java:

package me.sumithpuri.rest.app;   
   
  import java.util.HashSet;   
  import java.util.Set;   
  import javax.ws.rs.core.Application;   
  import me.sumithpuri.rest.webservice.ProductWebService;   
  import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;   
  import org.codehaus.jackson.map.AnnotationIntrospector;   
  import org.codehaus.jackson.map.ObjectMapper;   
  import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;   
   
  public class ProductApplication extends Application {   
    @Override   
    public Set<Class<?>> getClasses() {   
       Set<Class<?>> classes = new HashSet<Class<?>>();   
       classes.add(ProductWebService.class);   
       return classes;   
    }   
    @Override   
    public Set<Object> getSingletons() {   
       Set<Object> s = new HashSet<>();   
       ObjectMapper objMapper = new ObjectMapper();   
       AnnotationIntrospector primary = new JaxbAnnotationIntrospector();   
       AnnotationIntrospector secondary = new JaxbAnnotationIntrospector();   
       AnnotationIntrospector pair = AnnotationIntrospector.pair(primary, secondary);   
       objMapper.getDeserializationConfig().withAnnotationIntrospector(pair);   
       objMapper.getSerializationConfig().withAnnotationIntrospector(pair);   
       JacksonJaxbJsonProvider jaxbProvider = new JacksonJaxbJsonProvider();   
       jaxbProvider.setMapper(objMapper);   
       s.add(jaxbProvider);   
       return s;   
    }   
  }   

Next, change the Apache Wink configuration in the file web.xml as follows:

    
   <?xml version="1.0" encoding="UTF-8"?>   
 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">   
   <display-name>products</display-name>   
   <servlet>   
     <servlet-name>restService</servlet-name>   
     <servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>   
     <init-param>   
       <!-- <param-name>applicationConfigLocation</param-name> -->   
       <!-- <param-value>/WEB-INF/application</param-value> -->   
       <param-name>javax.ws.rs.Application</param-name>   
       <param-value>me.sumithpuri.rest.app.ProductApplication</param-value>   
     </init-param>   
   </servlet>   
   <servlet-mapping>   
     <servlet-name>restService</servlet-name>   
     <url-pattern>/rest/*</url-pattern>   
   </servlet-mapping>   
 </web-app>   

The next step is to add the relevant method to the web service and mark that it returns JSON. Here is the code to achieve this:

  
 @GET   
    @Path("/json/{id}")   
    @Produces(MediaType.APPLICATION_JSON)   
    public Product getProductJsonById(@PathParam(value="id") long id) {   
       Product product = persistenceManager.getProduct(id);   
       return product;   
    }   


Now, add the method to the client to test out the method and see if it works:

  public void invokeJSONGET(long id) {   
       System.out.println("Testing JSON GET command....");      
       RestClient restClient = new RestClient(clientConfig);   
       Resource resource = restClient.resource(REST_WEB_SERVICE+"/json/"+id);   
       ClientResponse response=resource.accept(MediaType.APPLICATION_JSON).get();   
       System.out.println("...JSON GET command is successful");   
    }   


In your Internet browser, navigate to the following address: http://localhost:8080/products/rest/product/json/3

 {"id":3,"name":"Sumith Puri"}  

There you have it – you have successfully started a JAX-RS/REST web service using Apache Wink!

Latest Posts

Related Stories