Monday, September 15, 2014

REST: Adding JSON support using jackson on weblogic 10.3.4

In my previous blog http://sanjeev-adf-webcenter.blogspot.in/2014/09/rest-service-on-weblogic-1034.html I showed how to create a RESTful service on weblogic 10.3.4

In this blog I am going to show how to provide JSON response from webservice using jackson apis.

jackson libraries are used to convert a JSON message into a java object and also java object to a JSON message.

We need to follow these steps
1. Configure weblogic for jackson libraries
2. Add jackson libraries to jdev project
3. Write pojos which needs to be exposed as JSON
4. Write service method and configure web.xml with Jersey servlet
5.  Deploy project on weblogic
6. Test

===================================================
1. Configure weblogic for jackson libraries

 Similarly as in previous blog we have added jersey libraries as a shared libraries in weblogic, this time we need to add jackson libraries. These libraries are available under $WL_HOME/common/deployable-libraries
 We need to add jackson-core-asl, jackson-jaxrs, jackson-mapper-asl libraries. For detail steps about how to add libraries see blog 'http://sanjeev-adf-webcenter.blogspot.in/2014/09/rest-service-on-weblogic-1034.html'


2. Add jackson libraries to jdev project

 For design time support of jackson libraries we need to add jackson libraries to our project.
 Follow these steps
a. Navigate to project properties > Library and classpath
b. Add Library 'JAX-RS Jersey Jacson (Bundle)' as shown below



For runtime support configure weblogic.xml so that code can refer to shared libraries of weblogic that we have installed in first step.



3. Write POJOs which needs to be exposed as JSON

As I said earlier jackson libraries can be used to convert java objects to JSON message and vice versa. We need to create POJO objects which needs to be represented in JSON. In this example I am creating employee and address pojos as shown below

Employee.java
package com.san.rest.entity;
import java.util.List;
public class Employee {
    private Long empId;
    private String name;
    private List addresses;   
    public Employee() {
        super();
    }

    public void setEmpId(Long empId) {
        this.empId = empId;
    }
    public Long getEmpId() {
        return empId;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setAddresses(List addresses) {
        this.addresses = addresses;
    }
    public List getAddresses() {
        return addresses;
    }
}

Address.java
package com.san.rest.entity;

public class Address {
    private Long addressId;
    private String addressType;
    private String line1;
    private String line2;
    private String city;
    private String state;
    private String country;
    private String zipCode;
    public Address() {
        super();
    }

    public void setAddressId(Long addressId) {
        this.addressId = addressId;
    }

    public Long getAddressId() {
        return addressId;
    }

    public void setAddressType(String addressType) {
        this.addressType = addressType;
    }

    public String getAddressType() {
        return addressType;
    }

    public void setLine1(String line1) {
        this.line1 = line1;
    }

    public String getLine1() {
        return line1;
    }

    public void setLine2(String line2) {
        this.line2 = line2;
    }

    public String getLine2() {
        return line2;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getCity() {
        return city;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getCountry() {
        return country;
    }

    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }

    public String getZipCode() {
        return zipCode;
    }
}


NOTE: There is a one to many relationship in these two classes. One employee can have multiple addresses. We have included an instance variable addresses of type List in Employee class.

4. Write service method and configure web.xml with Jersey servlet

 Create new class EmployeeService in package com.san.rest.service
 NOTE: This package is already configured to have Jersey service classes in previous blog. It is done by creating entry in web.xml. See previous blog http://sanjeev-adf-webcenter.blogspot.in/2014/09/rest-service-on-weblogic-1034.html

EmployeeService.java
package com.san.rest.service;

import com.san.rest.entity.Address;
import com.san.rest.entity.Employee;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;


@Path("employee")
public class EmployeeService {
    public EmployeeService() {
        super();
    }
   
    // To generate json
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public String getEmployeeDetails() {
       
                                                  
        Address a1 = new Address();
        a1.setAddressId(1L);
        a1.setAddressType("PERMANENT");
        a1.setLine1("Flat 1 ABC appartment");
        a1.setLine2("3rd Cross 1st Mian, MG Area");
        a1.setCity("Delhi");
        a1.setCountry("India");
        a1.setZipCode("00000");
       
        Address a2 = new Address();
        a2.setAddressId(2L);
        a2.setAddressType("CORRESPONDANCE");
        a2.setLine1("Flat 2 XYZ appartment");
        a2.setLine2("9th Cross 1st Mian, MG Area");
        a2.setCity("Bangalore");
        a2.setCountry("India");
        a2.setZipCode("99999");
       
        List addrList = new ArrayList();
        addrList.add(a1);
        addrList.add(a2);
       
        Employee e1 = new Employee();
        e1.setEmpId(1L);
        e1.setName("Sanjeev");
        e1.setAddresses(addrList);
       
        StringWriter output = new StringWriter();                                          
        ObjectMapper mapper = new ObjectMapper();
        try {
            mapper.writeValue(output, e1);
           
        } catch (JsonGenerationException e) {
            throw new RuntimeException("JsonGenerationException: " + e.getMessage());       
        } catch (JsonMappingException e) {
            throw new RuntimeException("JsonMappingException: " + e.getMessage());
        } catch (IOException e) {
            throw new RuntimeException("IOException: " + e.getMessage());
        }
       
        return output.toString();
    }

}



Important parts of this class are
a. Import of jackson classes: These classes are available from jackson libraries that we have added in project.
b. @Path("employee"): It means we need to add /employee in our url while calling this service
c. @GET: It means a get service
d. @Produces(MediaType.APPLICATION_JSON): It means response is of type JSON
e. Populate Employee/Address objects: As this is just a demo to show JSON response, I have created employee/address object inside service method itself but in general I would like to call a utility method or EJB session bean to provide me data about Employee/Address objects
f.  mapper.writeValue(output, e1): This method converts employee object e1 into its JSON representation.

Once again we can see our web.xml entry
    <servlet>
        <display-name>Rest Jersey Application</display-name>
        <servlet-name>RestJerseyApp</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.san.rest.service</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>RestJerseyApp</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

      


5.  Deploy project on weblogic
 Create a war profile and deploy it on weblogic server. Note down context root while creating war profile. Also explained in previous blog http://sanjeev-adf-webcenter.blogspot.in/2014/09/rest-service-on-weblogic-1034.html


6. Test




Disclaimer: Any views or opinions presented in this blog are solely those of the author and do not necessarily represent those of the company.

4 comments:

Anonymous said...

Thanks Sanjeev! This was very helpful.
Rohit.

Sanjeev Chauhan said...

You are welcome. Good to see it helped someone.

Unknown said...

Hi , In the $WL_HOME/common/deployable-libraries ,there is no Jackson Libraries , l only found Jersey Libraries . Where can l get Jackson Library . lm using JDeveloper Studio Edition Version 12.2.1.0.0 . Does you tutorial solve my problem located here https://community.oracle.com/message/13885636#13885636

Sanjeev Chauhan said...

You can download jackson from http://www.java2s.com/Code/Jar/j/Downloadjacksonall190jar.htm
jackson or JSONBeanSerializationHelper both seems to be doing same thing. You might end with same issues. I have provided an alternative in your forum.