Showing posts with label JSON. Show all posts
Showing posts with label JSON. Show all posts

Saturday, December 1, 2012

RESTful with RESTEasy - Part 2/4 (Client Consuming a POST and GET RESTful Service)

Overview:
This post looks at how to write a service client using RESTEasy framework, which is an excellent framework for developing RESTful services, and has gained a lot of popularity in the Mobile application development world.

Also Refer to,
RESTful with RESTEasy - Part 1/4 (Creating a POST and GET RESTful Service)

You can find the sample code here.

Prerequisite:JDK >= 1.5.x
Maven >= 2.2.x


Step 1: Maven Dependencies (pom.xml)
Update your client project's pom.xml by adding the following RESTEasy dependency.

 <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">  
   . . .
   <dependencies>  
     . . .  
     <dependency>  
       <groupId>org.jboss.resteasy</groupId>  
       <artifactId>resteasy-jaxrs</artifactId>  
       <version>${resteasy.version}</version>  
     </dependency>  
    . . .
   </dependencies>  
   . . .
 </project>  

Step 2: How to create a requests

   private static final String SERVICE_URL = "http://localhost:8080/greetingspring";  
   private static final String SERVICE_URL_ADD = "/add";  
   private static final String SERVICE_URL_UPDATED = "/update";  
   private static final String SERVICE_URL_GET = "/get/{id}";  
   private static final String SERVICE_URL_GET_ALL = "/getAll";  
   . . .  
   private static ClientRequest createRequest(String uri) {  
     ClientRequest request = new ClientRequest(SERVICE_URL + uri);  
     request.accept("application/json");  
     return request;  
   }  
   . . .  
   ClientRequest request = createRequest(SERVICE_URL_ADD)  
   ClientRequest request = createRequest(SERVICE_URL_GET)  
   ClientRequest request = createRequest(SERVICE_URL_UPDATE)  
   ClientRequest request = createRequest(SERVICE_URL_GET_ALL)  

Creating a POST request
 private static Long addUser(User newUser) throws Exception {  
     String requestJson = "{\"user\":" + JSON_CONVERTER.toJson(newUser) + "}";  
     displayRequest(requestJson);  
     ClientRequest request = createRequest(SERVICE_URL_ADD).body(CONTENT_TYPE, requestJson);  
     ClientResponse<String> response = request.post(String.class);  
     displayResponse(response, HTTP_CODE_CREATED);  
     return Long.parseLong(response.getEntity().toString());  
   }  

Creating a GET request
 private static User getUser(Long userId) throws Exception {  
     ClientRequest request = createRequest(SERVICE_URL_GET.replace("{id}", userId.toString()));  
     ClientResponse<String> response = request.get(String.class);  
     displayResponse(response, HTTP_CODE_OK);  
     String responseJson = response.getEntity().toString();  
     responseJson = responseJson.replace("{\"user\":", "").replace("}}", "}");  
     return JSON_CONVERTER.fromJson(responseJson, User.class);  
   }  

Complete Code for the Client


 package org.fazlan.resteasy.spring.client;  
 import com.google.gson.Gson;  
 import org.fazlan.resteasy.spring.entity.User;  
 import org.jboss.resteasy.client.ClientRequest;  
 import org.jboss.resteasy.client.ClientResponse;  
 import java.io.BufferedReader;  
 import java.io.ByteArrayInputStream;  
 import java.io.IOException;  
 import java.io.InputStreamReader;  

 public class RestClient {  

   private static final String SERVICE_URL = "http://localhost:8080/greetingspring";  
   private static final String SERVICE_URL_ADD = "/add";  
   private static final String SERVICE_URL_UPDATED = "/update";  
   private static final String SERVICE_URL_GET = "/get/{id}";  
   private static final String SERVICE_URL_GET_ALL = "/getAll";  
   private static final String CONTENT_TYPE = "application/json";  
   private static final Gson JSON_CONVERTER = new Gson();  
   private static final int HTTP_CODE_OK = 200;  
   private static final int HTTP_CODE_CREATED = 201;  

   public static void main(String[] args) throws Exception {  
     User newUser = new User("Firstname", "Lastname");  
     Long userId = addUser(newUser);  
     User user = getUser(userId);  
     displayUser(user);  
     user.setFirstName("Updated " + user.getFirstName());  
     userId = updateUser(user);  
     user = getUser(userId);  
     displayUser(user);  
     addUser( new User("AnotherFirstName", "AnotherLastName"));  
     getAllUsers();  
   }  
   private static Long addUser(User newUser) throws Exception {  
     String requestJson = "{\"user\":" + JSON_CONVERTER.toJson(newUser) + "}";  
     displayRequest(requestJson);  
     ClientRequest request = createRequest(SERVICE_URL_ADD).body(CONTENT_TYPE, requestJson);  
     ClientResponse<String> response = request.post(String.class);  
     displayResponse(response, HTTP_CODE_CREATED);  
     return Long.parseLong(response.getEntity().toString());  
   }  
   private static Long updateUser(User user) throws Exception {  
     String requestJson = "{\"user\":" + JSON_CONVERTER.toJson(user) + "}";  
     displayRequest(requestJson);  
     ClientRequest request = createRequest(SERVICE_URL_UPDATED).body(CONTENT_TYPE, requestJson);  
     ClientResponse<String> response = request.post(String.class);  
     displayResponse(response, HTTP_CODE_OK);  
     return Long.parseLong(response.getEntity().toString());  
   }  
   private static User getUser(Long userId) throws Exception {  
     ClientRequest request = createRequest(SERVICE_URL_GET.replace("{id}", userId.toString()));  
     ClientResponse<String> response = request.get(String.class);  
     displayResponse(response, HTTP_CODE_OK);  
     String responseJson = response.getEntity().toString();  
     responseJson = responseJson.replace("{\"user\":", "").replace("}}", "}");  
     return JSON_CONVERTER.fromJson(responseJson, User.class);  
   }  
   private static void getAllUsers() throws Exception {  
     ClientRequest request = createRequest(SERVICE_URL_GET_ALL);  
     ClientResponse<String> response = request.get(String.class);  
     displayResponse(response, HTTP_CODE_OK);  
   }  
   private static ClientRequest createRequest(String uri) {  
     ClientRequest request = new ClientRequest(SERVICE_URL + uri);  
     request.accept("application/json");  
     return request;  
   }  
   private static void displayUser(User user) {  
     System.out.println(user);  
   }  
   private static void displayRequest(String request) {  
     System.out.println(request);  
   }  
   private static void displayResponse(ClientResponse<String> response, int expectedResponseCode) throws IOException {  
     if (response.getStatus() != expectedResponseCode) {  
       throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());  
     }  
     BufferedReader br = new BufferedReader(new InputStreamReader(  
         new ByteArrayInputStream(response.getEntity().getBytes())));  
     String output;  
     System.out.println("Output from Server .... \n");  
     while ((output = br.readLine()) != null) {  
       System.out.println(output);  
     }  
   }  
 }  

Summary:
This tutorial looked at how we can consume RESTful Web Service using RESTEasy.

You can find the sample code here.

RESTful with RESTEasy - Part 1/4 (Creating a POST and GET RESTful Service)

Overview:
This post looks at RESTEasy framework, which is an excellent framework for developing RESTful services, and has gained a lot of popularity in the Mobile application development world.


Also Refer to,
RESTful with RESTEasy - Part 2/4 (Client Consuming a POST and GET RESTful Service)


You can find the sample code here.

Prerequisite:JDK >= 1.5.x
Maven >= 2.2.x

Project Structure: Following is the project structure I have used (Maven WAR project).

mvn archetype:generate -DgroupId=org.fazlan.resteasy.spring.servic -DartifactId=org.fazlan.resteasy.spring.servic -DarchetypeArtifactId=maven-archetype-webapp -Dversion=1.0.0-SNAPSHOT -DinteractiveMode=false



Step 1: Maven Dependencies (pom.xml)

 <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>org.fazlan</groupId>  
   <artifactId>org.fazlan.resteasy.spring.service</artifactId>  
   <packaging>war</packaging>  
   <version>1.0.0</version>  
   <name>org.fazlan.resteasy.spring.service Maven Webapp</name>  
   <url>http://maven.apache.org</url>  
   <properties>  
     <resteasy.version>2.3.4.Final</resteasy.version>  
     <org.springframework.version>3.1.2.RELEASE</org.springframework.version>  
     <slf4j.version>1.6.1</slf4j.version>  
   </properties>  
   <dependencies>  
     <!-- Spring 3 dependencies -->  
     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-core</artifactId>  
       <version>3.1.2.RELEASE</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-web</artifactId>  
       <version>3.1.2.RELEASE</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-webmvc</artifactId>  
       <version>3.1.2.RELEASE</version>  
     </dependency>  
     <!-- jstl -->  
     <dependency>  
       <groupId>javax.servlet</groupId>  
       <artifactId>jstl</artifactId>  
       <version>1.2</version>  
     </dependency>  
     <dependency>  
       <groupId>org.jboss.resteasy</groupId>  
       <artifactId>resteasy-jaxrs</artifactId>  
       <version>${resteasy.version}</version>  
     </dependency>  
     <dependency>  
       <groupId>org.jboss.resteasy</groupId>  
       <artifactId>resteasy-jaxb-provider</artifactId>  
       <version>${resteasy.version}</version>  
     </dependency>  
     <dependency>  
       <groupId>org.jboss.resteasy</groupId>  
       <artifactId>resteasy-spring</artifactId>  
       <version>${resteasy.version}</version>  
       <exclusions>  
         <exclusion>  
           <artifactId>commons-logging</artifactId>  
           <groupId>commons-logging</groupId>  
         </exclusion>  
         <exclusion>  
           <artifactId>jaxb-impl</artifactId>  
           <groupId>com.sun.xml.bind</groupId>  
         </exclusion>  
         <exclusion>  
           <artifactId>sjsxp</artifactId>  
           <groupId>com.sun.xml.stream</groupId>  
         </exclusion>  
         <exclusion>  
           <artifactId>jsr250-api</artifactId>  
           <groupId>javax.annotation</groupId>  
         </exclusion>  
         <exclusion>  
           <artifactId>activation</artifactId>  
           <groupId>javax.activation</groupId>  
         </exclusion>  
       </exclusions>  
     </dependency>  
     <dependency>  
       <groupId>junit</groupId>  
       <artifactId>junit</artifactId>  
       <version>3.8.1</version>  
       <scope>test</scope>  
     </dependency>  
     <dependency>  
       <groupId>com.google.code.gson</groupId>  
       <artifactId>gson</artifactId>  
       <version>1.7.1</version>  
     </dependency>  
   </dependencies>  
   <build>  
     <finalName>UserService</finalName>  
     <plugins>  
       <plugin>  
         <groupId>org.mortbay.jetty</groupId>  
         <artifactId>maven-jetty-plugin</artifactId>  
         <version>6.1.10</version>  
         <configuration>  
           <contextPath>UserService</contextPath>  
           <scanIntervalSeconds>30</scanIntervalSeconds>  
           <stopKey>foo</stopKey>  
           <stopPort>9999</stopPort>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  
 </project>  

Step 2: Creating POJO Classes and Service Implementation

User.java

 package org.fazlan.resteasy.spring.entity; 
 
 import javax.xml.bind.annotation.XmlRootElement;  

 @XmlRootElement  
 public class User {  

   private long id;  
   private String firstName;  
   private String lastName;  

   public User() {  
   }  

   public User(String firstName, String lastName) {  
     this.firstName = firstName;  
     this.lastName = lastName;  
   }  

   public long getId() {  
     return id;  
   }  

   @Override  
   public String toString() {  
     return "User{" +  
         "id=" + id +  
         ", firstName='" + firstName + '\'' +  
         ", lastName='" + lastName + '\'' +  
         '}';  
   }  

   public void setId(long id) {  
     this.id = id;  
   }  

   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;  
   }  
 }  


UserService.java - The Service Interface
 package org.fazlan.resteasy.spring.service;  
 import org.fazlan.resteasy.spring.entity.User;  
 import javax.ws.rs.*;  
 import javax.ws.rs.core.MediaType;  
 import javax.ws.rs.core.Response;  

 @Path("/")  
 public interface UserService {  

   @POST  
   @Path("/add")  
   @Consumes(MediaType.APPLICATION_JSON)  
   Response add(User user);  

   @POST  
   @Path("/update")  
   @Consumes(MediaType.APPLICATION_JSON)  
   Response update(User user);  

   @GET  
   @Path("/get/{id}")  
   @Produces(MediaType.APPLICATION_JSON)  
   Response get(@PathParam("id") long id);  

   @GET  
   @Path("/getAll")  
   @Produces(MediaType.APPLICATION_JSON)  
   Response getAll();  
 }  

NOTE: This service class has been annotated to produce and consume certain methods in JSON(application/json) as the mime-type.

UserServiceImpl.java - Service Implementation
 package org.fazlan.resteasy.spring.service;  
 
 import org.fazlan.resteasy.spring.entity.User;  
 import org.springframework.stereotype.Component;  
 import javax.ws.rs.PathParam;  
 import javax.ws.rs.core.GenericEntity;  
 import javax.ws.rs.core.Response;  
 import java.util.Collection;  
 import java.util.HashMap;  
 import java.util.Map;  

 @Component  
 public class UserServiceImpl implements UserService {  

   private static long ID = 0L;  
   private static Map<Long, User> users = new HashMap<Long, User>();  

   public Response add(User user) {  
     user.setId(++ID);  
     update(user);  
     return Response.status(Response.Status.CREATED).entity(ID).build();  
   }  

   public Response update(User user) {  
     users.put(ID, user);  
     return Response.status(Response.Status.OK).entity(ID).build();  
   }  

   public Response get(@PathParam("id") long id) {  
     return Response.status(Response.Status.OK).entity(users.get(id)).build();  
   }  

   public Response getAll() {  
     GenericEntity<Collection<User>> usersEntity = new GenericEntity<Collection<User>>(users.values()) {  
     };  
     return Response.status(Response.Status.OK).entity(usersEntity).build();  
   }  
 }  

Step 3: Exposing the Service Beans as RESTful Web Service (applicationContext.xml)

 <?xml version="1.0" encoding="UTF-8"?>  
 <beans xmlns="http://www.springframework.org/schema/beans"  
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
     xmlns:context="http://www.springframework.org/schema/context"  
     xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
       http://www.springframework.org/schema/context  
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
   <context:annotation-config/>  
   <context:component-scan base-package="org.fazlan.resteasy.spring.service"/>  
 </beans>  

NOTE: This will scan all the Spring components defined in the source and load them into the Application's Spring context.

Step 4: Updating the web.xml to register the RESTEasy Servlet.
 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xmlns="http://java.sun.com/xml/ns/javaee"  
      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>Restful Web Application</display-name>  
   <!--<context-param>-->  
   <!--<param-name>resteasy.scan</param-name>-->  
   <!--<param-value>true</param-value>-->  
   <!--</context-param>-->  
   <context-param>  
     <param-name>contextConfigLocation</param-name>  
     <param-value>classpath:applicationContext.xml</param-value>  
   </context-param>  
   <listener>  
     <listener-class>  
       org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap  
     </listener-class>  
   </listener>  
   <listener>  
     <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>  
   </listener>  
   <servlet>  
     <servlet-name>resteasy-servlet</servlet-name>  
     <servlet-class>  
       org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher  
     </servlet-class>  
   </servlet>  
   <servlet-mapping>  
     <servlet-name>resteasy-servlet</servlet-name>  
     <url-pattern>/*</url-pattern>  
   </servlet-mapping>  
 </web-app>  


Step 5: Building the Project
mvn clean install

Step 6: Deploying the Service
Now you can deploy this service on to any container. Here we'll deploy this on Jetty using Maven.

mvn jetty:run

This should start a Jetty instance and deploy the application. You can access the HTTP GET service endpoints at the following endpoints.

http://localhost:8080/UserService/get/1 - Get the user with Id = 1
http://localhost:8080/UserService/getAll - List all users

Step 7: Testing the RESTful Web Service using CURL


We're going to test our Web Service using CURL, which I found as a very easy way to send REST Calls. I found this very nice blog about RESTing with Curl.

Installing CURL

sudo apt-get install curl

-I am using Ubuntu, if you're using Win or Mac, please do the necessary to install curl.

Now, after successfully installing CURL, we are ready to test the services.

GET Resources:
- Retrieving all the users.
 curl -v -H "Accept: application/json" http://localhost:8080/UserService/getAll

- Retrieving a user for a given id(id = 1).
 curl -v -H "Accept: application/json" http://localhost:8080/UserService/get/1

POST a Resource: Adding a new user resource.
- Adding the new user record in the add.json file.
 { 
  "user":{ 
    "id":1, 
    "firstName":"First Name1", 
    "lastName":"Last Name1" 
  } 
} 

 curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d @add.json http://127.0.0.1:8080/UserService/add


PUT a Resource: Updating an existing user resource.
- Updating an existing user record in the update.json file.
 { 
  "user":{ 
    "id":1, 
    "firstName":"Updated First Name1", 
    "lastName" :"Updated Last Name1" 
  } 
} 

 curl -v -H "Accept: application/json" -H "Content-type: application/json" -X PUT -d @update.json http://127.0.0.1:8080/UserService/update/

Summary:
This tutorial looked at how we can create RESTful Web Service using RESTEasy and test the services using CURL.

You can find the sample code here.

Monday, May 28, 2012

jQuery Tutorial: Integrating with Flickr's JSON API

Overview:
This will be another article on jQuery. Here, we'll be mainly focusing on how jQuery eases the usage of the Ajax API for JSON.

You may also refer to the first jQuery article "jQuery Tutorial: Ajax Processing - GET and POST".

The sample code for this article can be found here.

Application Demo:
The application displays images from Flickr.com that are tagged by the input provided by the user.

Home page:


Displaying the Result:



Project Structure:

 org.fazlan.jquery.flickr.app  
 |-- pom.xml  
 `-- src  
   `-- main  
     |-- resources  
     `-- webapp  
       |-- img  
       |  `-- ajax-loader.gif  
       |-- index.jsp  
       |-- jquery.js  
       `-- WEB-INF  
         `-- web.xml  

Step 1: Creating a the Web Project.

 <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>org.fazlan</groupId>  
   <artifactId>org.fazlan.jquery.flickr.app</artifactId>  
   <packaging>war</packaging>  
   <version>1.0.0-SNAPSHOT</version>  
   <name>org.fazlan.jquery.flickr.app Maven Webapp</name>  
   <url>http://maven.apache.org</url>  
   <dependencies>  
     <dependency>  
       <groupId>junit</groupId>  
       <artifactId>junit</artifactId>  
       <version>3.8.1</version>  
       <scope>test</scope>  
     </dependency>  
   </dependencies>  
   <build>  
     <finalName>jquery.flickr.app</finalName>  
     <plugins>  
       <plugin>  
         <groupId>org.mortbay.jetty</groupId>  
         <artifactId>maven-jetty-plugin</artifactId>  
         <version>6.1.10</version>  
       </plugin>  
       <plugin>  
         <groupId>org.apache.maven.plugins</groupId>  
         <artifactId>maven-compiler-plugin</artifactId>  
         <version>2.4</version>  
         <configuration>  
           <source>1.6</source>  
           <target>1.6</target>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  
 </project>  

Step 2: Verifying the Flickr Endpoint

Click on the following link, this will generate a JSON output from Flickr.com.

http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?


Step 3: Defining the JSP


index.jsp
 <html>  
 <head>  
   <title>Flicker Image Library</title>  
   <script type="text/javascript" src="jquery.js"></script>  
   <script type="text/javascript">  
     // jQuery document ready
  
     $(function() {  
 /*  
            $("#tagDiv").ajaxStart(function(){  
             $('#loadImg').show();   
          });  
            $("#tagDiv").ajaxComplete(function(){  
             $('#loadImg').hide();   
          });  
 */  

       // when hit Enter on the text field  
       $('#tagField').keypress( function(evnt) {  
             var code = (evnt.keyCode ? evnt.keyCode : e.which);  
           // code to trap 'Enter' key  
           if( code == 13 ) {  
             getFlickrImages();  
           }  
       });  

       // when clicked on search button  
       $('#exploreBtn').click(function() {  
         getFlickrImages();  
       });  
     });  

     function getFlickrImages() {  
      var data = 'tags=' + $('#tagField').val().trim() + '&tagmode=any&format=json&jsoncallback=?';  
      $('#loadImg').show();  

     // sending a AJAX call to the flickr and expect JSON as return type  
      $.ajax({  
        type: 'GET',  
        url: 'http://api.flickr.com/services/feeds/photos_public.gne',  
        data: data,  
        dataType: 'json',  
        error: function(xhr, status, error) {  
             alert(status + '--> ' + error);  
           },  
        success: function(data) {  
             $('#loadImg').hide();                    
             $('#contentDiv').html(data.title);  
             $('#resultDiv').html('<center><table id="imageTable" style="border: 1px solid black; text-align:center"><tr></tr></table></center>');  
             $.each(data.items, function(index, item) {  
              // show FIVE images per row  
              if( index%5 == 0 ) {  
                   $('#imageTable tr:last').after('<tr></tr>')  
              }   
              //$('#imageTable tr:last').append('<td><img src=' + item.media.m + '></td>');    
              $('#imageTable tr:last').append('<td>' + item.description + '</td>');                           
             });  
         }  
      });  
     }  
   </script>  
 </head>  
 <body>  
 <h1 style="color: blue">Flicker Image Library</h1>  
 <div style="border: 1px solid blue" id="tagDiv">  
   <table style="color: blue">  
     <tr valign="middle">  
       <td><b>Tag Name</b></td>  
        <td><input type="text" id="tagField"/></td>  
       <td><button id="exploreBtn">Explore</button></td>  
       <td><img src="img/ajax-loader.gif" id="loadImg" style="display: none"/></td>  
     </tr>      
   </table>  
 </div>  
 <br>  
 <div id="contentDiv" style="border: 1px solid blue; color: blue"></div>  
 <div id="resultDiv"></div>  
 </body>  
 </html>  


The above Ajax call gives you more control over how you need to make the Ajax call. Conversely, you could also try the following:


var data = 'tags=' + $('#tagField').val().trim() + '&tagmode=any&format=json&jsoncallback=?';  

$.getJSON('http://api.flickr.com/services/feeds/photos_public.gne',  
      data,  
      function(result) {  
        $('#loadImg').hide();                    
        $('#contentDiv').html(result.title);  
        $('#resultDiv').html('<center><table id="imageTable" style="border: 1px solid black; text-align:center"><tr></tr></table></center>');  
        $.each(result.items, function(index, item) {  
         // show FIVE images per row  
         if( index%5 == 0 ) {  
             $('#imageTable tr:last').after('<tr></tr>')  
         }   
         //$('#imageTable tr:last').append('<td><img src=' + item.media.m + '></td>');    
         $('#imageTable tr:last').append('<td>' + item.description + '</td>');                           
        });  
 });  
Step 4: Building and Deploying the Application

$ mvn clean install
$ mvn jetty:run

mvn:jetty:run - would run the web app on the jetty server.

Now, you can access the application with the following URL.
http://localhost:8080/org.fazlan.jquery.flickr.app

Summary:
This article looked at how jQuery can be used to easily manipulate Javascript and simplify the usage of Ajax API for JSON.

The sample code for this article can be found here.

Sunday, April 15, 2012

Json Tutorial: Java to Json with Google Gson

Overview:
This article looks how you can easily transform Java objects into Json representation and vice versa using Google Gson library.

Project Structure:



Step 1: Maven Dependencies (pom.xml)
 <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>org.fazlan</groupId>  
  <artifactId>org.fazlan.json.gson</artifactId>  
  <packaging>jar</packaging>  
  <version>1.0.0-SNAPSHOT</version>  
  <name>org.fazlan.json.gson</name>  
  <url>http://maven.apache.org</url>  
  <dependencies>  
   <dependency>  
    <groupId>junit</groupId>  
    <artifactId>junit</artifactId>  
    <version>3.8.1</version>  
    <scope>test</scope>  
   </dependency>  
   <dependency>  
    <groupId>com.google.code.gson</groupId>  
    <artifactId>gson</artifactId>  
    <version>2.1</version>  
    <scope>compile</scope>  
   </dependency>  
    <dependency>  
      <groupId>org.apache.ws.commons.schema</groupId>  
      <artifactId>XmlSchema</artifactId>  
      <version>1.4.7-wso2v1</version>  
    </dependency>  
  </dependencies>  
 </project>  

Step 2: The Java Class we wish to transform into Json and vice versa
 package org.fazlan.json;  
 public class Person {  
   private Long id;  
   private String firstName;  
   private String lastName;  
   public Person(Long id, String firstName, String lastName) {  
     this.id = id;  
     this.firstName = firstName;  
     this.lastName = lastName;  
   }  
   public Long getId() {  
     return id;  
   }  
   public void setId(Long id) {  
     this.id = id;  
   }  
   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;  
   }  
   @Override  
   public String toString() {  
     return "Person{" +  
         "id=" + id +  
         ", firstName='" + firstName + '\'' +  
         ", lastName='" + lastName + '\'' +  
         '}';  
   }  
 }  

Step 3: The Util class that helps to do the transformation.
 package org.fazlan.json;  
 import com.google.gson.Gson;  
 public class Json {  
   private final Gson gson;  
   private static Json JSON;  
   private Json() {  
     gson = new Gson();  
   }  
   public static Json getInstance() {  
     if(JSON == null) {  
       JSON = new Json();  
     }  
     return JSON;  
   }  
   public String toJson(Object t) {  
      return gson.toJson(t);  
   }  
   public <T> T fromJson(String jsonString, Class<T> clazz) {  
     return gson.fromJson(jsonString, clazz);  
   }  
 }  

What's important to note is the following two methods in com.google.gson.Gson
 . . .  
   gson.toJson(t);  
 . . .  
   gson.fromJson(jsonString, clazz);  

Step 3: Writing a simple client to test application
 package org.fazlan.json;  
 public class Application {  
   public static void main(String... args) {  
     Json json = Json.getInstance();  
     System.out.println("Java to Json");  
     Person p1 = new Person(1L, "Json", "Json");  
     String jsonString = json.toJson(p1);  
     System.out.println(p1 + "\t-->\t" + jsonString);  
     System.out.println("-----------");  
     System.out.println("Json to Java");  
     String person2JsonString = "{\"id\":2,\"firstName\":\"Gson\",\"lastName\":\"Google\"}";  
     Person p2 = json.fromJson(person2JsonString, Person.class);  
     System.out.println(person2JsonString + "\t-->\t" + p2);  
   }  
 }  

Sample output from this application,
 Java to Json  
 Person{id=1, firstName='Json', lastName='Json'}     -->     {"id":1,"firstName":"Json","lastName":"Json"}  
 -----------  
 Json to Java  
 {"id":2,"firstName":"Gson","lastName":"Google"}     -->     Person{id=2, firstName='Gson', lastName='Google'}  

Thursday, April 12, 2012

Part 2: RESTful WS with Apache CXF - JSON

Overview:
This is Part 2 of the article on RESTful WS with Apache CXF. If you haven't looked at Part 1, I suggest you to do so.

This article looks at how you can do JSON/HTTP based RESTful WS with Apache CXF. We're using the CXF support on JAX-RS (JSR-311) for this. The sample code can be found here.

Prerequisite:JDK >= 1.5.x
Maven >= 2.2.x

Project Structure: Following is the project structure I have used (Maven WAR project).


Step 1: Maven Dependencies (pom.xml)
 <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>org.fazlan</groupId> 
  <artifactId>org.fazlan.employee.cxf.jsonrest.service</artifactId> 
  <packaging>war</packaging> 
  <version>1.0-SNAPSHOT</version> 
  <name>org.fazlan.employee.cxf.jsonrest.service</name> 
  <url>http://maven.apache.org</url> 
  <build> 
    <finalName>CXFEmployeeJsonRESTService</finalName> 
    <plugins> 
      <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-compiler-plugin</artifactId> 
        <configuration> 
          <source>1.6</source> 
          <target>1.6</target> 
        </configuration> 
      </plugin> 
    </plugins> 
  </build> 
  <dependencies> 
    <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>3.8.1</version> 
      <scope>test</scope> 
    </dependency> 
    <!-- Spring framework --> 
    <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-core</artifactId> 
      <version>${org.springframework.version}</version> 
    </dependency> 
    <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-web</artifactId> 
      <version>${org.springframework.version}</version> 
    </dependency> 
    <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.8.1</version> 
    </dependency> 
    <dependency> 
      <groupId>org.apache.cxf</groupId> 
      <artifactId>cxf-rt-frontend-jaxrs</artifactId> 
      <version>${cxf.version}</version> 
    </dependency> 
    <dependency> 
      <groupId>org.apache.cxf</groupId> 
      <artifactId>cxf-rt-databinding-aegis</artifactId> 
      <!-- 2.4.4 or 2.5.0 --> 
      <version>${cxf.version}</version> 
    </dependency> 
    <dependency> 
      <groupId>org.apache.xmlbeans</groupId> 
      <artifactId>xmlbeans</artifactId> 
      <version>2.4.0</version> 
    </dependency> 
  </dependencies> 
  <properties> 
    <org.springframework.version>3.1.1.RELEASE</org.springframework.version> 
    <cxf.version>2.4.6</cxf.version> 
  </properties> 
</project> 

Step 2: Creating POJO Classes and Service Implementation

Employee.java
 package org.fazlan.employee.cxf.jsonrest.service.beans; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 
import java.io.Serializable; 
@XmlType( 
    name = "EmployeeType", 
    namespace = "org.fazlan.employee.cxf.jsonrest.service.beans", 
    propOrder = {"id", "firstName", "lastName"}) 
@XmlRootElement( 
    name = "Employee", 
    namespace = "org.fazlan.employee.cxf.jsonrest.service.beans") 
public class Employee implements Serializable { 
  private Long id; 
  private String firstName; 
  private String lastName; 
  public Employee() { 
  } 
  public Employee(Long id, String firstName, String lastName) { 
    this.id = id; 
    this.firstName = firstName; 
    this.lastName = lastName; 
  } 
  public Long getId() { 
    return id; 
  } 
  public void setId(Long id) { 
    this.id = id; 
  } 
  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 boolean equals(Object o) { 
    if (this == o) return true; 
    if (!(o instanceof Employee)) return false; 
    Employee employee = (Employee) o; 
    return !(firstName != null ? !firstName.equals(employee.firstName) : employee.firstName != null) && 
        !(id != null ? !id.equals(employee.id) : employee.id != null) && 
        !(lastName != null ? !lastName.equals(employee.lastName) : employee.lastName != null); 
  } 
  public int hashCode() { 
    int result = id != null ? id.hashCode() : 0; 
    result = 31 * result + (firstName != null ? firstName.hashCode() : 0); 
    result = 31 * result + (lastName != null ? lastName.hashCode() : 0); 
    return result; 
  } 
  @Override 
  public String toString() { 
    return "Employee{" + 
        "id=" + id + 
        ", firstName='" + firstName + '\'' + 
        ", lastName='" + lastName + '\'' + 
        '}'; 
  } 
} 

Employees.java - This is used to hold a collection object of Employee.java
 package org.fazlan.employee.cxf.jsonrest.service.beans; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlElementWrapper; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 
import java.util.Collection; 
@XmlType( 
    name = "EmployeesType", 
    namespace = "org.fazlan.employee.cxf.jsonrest.service.beans") 
@XmlRootElement( 
    name = "Employees", 
    namespace = "org.fazlan.employee.cxf.jsonrest.service.beans") 
public class Employees { 
  private Collection<Employee> employees; 
  public Employees() { 
  } 
  public Employees(Collection<Employee> employees) { 
    setEmployees(employees); 
  } 
  @XmlElement(name = "employee",required = true) 
  @XmlElementWrapper(name = "employees") 
  public Collection<Employee> getEmployees() { 
    return employees; 
  } 
  public void setEmployees(Collection<Employee> employees) { 
    this.employees = employees; 
  } 
} 

IEmployeeService.java - Service Interface
 package org.fazlan.employee.cxf.jsonrest.service.services; 
import org.fazlan.employee.cxf.jsonrest.service.beans.Employee; 
import org.fazlan.employee.cxf.jsonrest.service.beans.Employees; 
import javax.ws.rs.core.Response; 
public interface IEmployeeService { 
  Employee get(Long id); 
  Employees getAll(); 
  Response add(Employee employee); 
  Response update(Employee employee); 
  Response delete(Long id); 
} 


EmployeeService.java - Implementation of the service.

NOTE: This service class has been annotated to produce and consume certain methods in JSON(application/json) as the mime-type. Read more about Apache CXF - JAX-RS basics.

 package org.fazlan.employee.cxf.jsonrest.service.services; 
import org.fazlan.employee.cxf.jsonrest.service.beans.Employee; 
import org.fazlan.employee.cxf.jsonrest.service.beans.Employees; 
import javax.ws.rs.*; 
import javax.ws.rs.core.Response; 
import java.util.HashMap; 
import java.util.Map; 
@Path("/employeeservice/") 
@Produces("application/json") 
public class EmployeeService implements IEmployeeService { 
  private static final Map<Long, Employee> EMPLOYEE_MAP = new HashMap<Long, Employee>(); 
  private static long index = 3L; 
  static { 
    EMPLOYEE_MAP.put(1L, new Employee(1L, "First Name 1", "Last Name 1")); 
    EMPLOYEE_MAP.put(2L, new Employee(2L, "First Name 2", "Last Name 2")); 
  } 
  @GET 
  @Path("/get/{id}") 
  public Employee get(@PathParam("id") Long id) { 
    return EMPLOYEE_MAP.get(id); 
  } 
  @GET 
  @Path("/getall/") 
  public Employees getAll() { 
    return new Employees(EMPLOYEE_MAP.values()); 
  } 
  @POST 
  @Path("/add/") 
  @Consumes("application/json") 
  public Response add(Employee employee) { 
    System.out.println("Adding :" + employee); 
    employee.setId(index++); 
    update(employee); 
    return Response.status(Response.Status.OK).build(); 
  } 
  @PUT 
  @Path("/update/") 
  @Consumes("application/json") 
  public Response update(Employee employee) { 
    System.out.println("Updating :" + employee); 
    EMPLOYEE_MAP.put(employee.getId(), employee); 
    return Response.status(Response.Status.OK).build(); 
  } 
  @DELETE 
  @Path("/delete/{id}/") 
  public Response delete(@PathParam("id") Long id) { 
    Employee e = EMPLOYEE_MAP.remove(id); 
    System.out.println("Deleted :" + e); 
    return Response.status(Response.Status.OK).build(); 
  } 
} 


Read more about Apache CXF - JAX-RS basics.

Step 3: Exposing the Service Beans as RESTful Web Service
 <?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:jaxrs="http://cxf.apache.org/jaxrs" 
    xmlns:cxf="http://cxf.apache.org/core" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
              http://www.springframework.org/schema/beans/spring-beans.xsd 
              http://cxf.apache.org/jaxrs 
              http://cxf.apache.org/schemas/jaxrs.xsd 
              http://cxf.apache.org/core 
              http://cxf.apache.org/schemas/core.xsd"> 
  <!-- do not use import statements if CXFServlet init parameters link to this beans.xml --> 
  <import resource="classpath:META-INF/cxf/cxf.xml"/> 
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> 
  <jaxrs:server id="employeeService" address="/"> 
    <jaxrs:serviceBeans> 
      <ref bean="employeeServiceBean"/> 
    </jaxrs:serviceBeans> 
    <jaxrs:extensionMappings> 
      <entry key="xml" value="application/xml" /> 
      <entry key="json" value="application/json" /> 
    </jaxrs:extensionMappings> 
    <jaxrs:features> 
      <cxf:logging/> 
    </jaxrs:features> 
  </jaxrs:server> 
  <bean id="employeeServiceBean" class="org.fazlan.employee.cxf.jsonrest.service.services.EmployeeService"/> 
</beans> 

Step 4: Updating the web.xml to Register the CXF Servlet.
 <!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>CXF Web Service Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/app-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Step 5: Building the Project
mvn clean install

Step 6: Deploying the Service
Now you can deploy this service on to any container. Here we'll deploy this on Tomcat server.

Step 7: Testing the RESTful Web Service using CURL

We're going to test our Web Service using CURL, which I found as a very easy way to send REST Calls. I found this very nice blog about RESTing with Curl.

Installing CURL

sudo apt-get install curl

-I am using Ubuntu, if you're using Win or Mac, please do the necessary to install curl.

Now, after successfully installing CURL, we are ready to test the services.

GET Resources:
- Retrieving all the employee resources.
 curl -v -H "Accept: application/json" http://localhost:8080/CXFEmployeeJsonRESTService/employeeservice/getall

- Retrieving a employee resource for a given id(id = 1).
 curl -v -H "Accept: application/json" http://localhost:8080/CXFEmployeeJsonRESTService/employeeservice/get/1

POST a Resource: Adding a new employee resource.
- Adding the new employee record in the add.json file.
 { 
  "ns1.Employee":{ 
    "id":1, 
    "firstName":"First Name1", 
    "lastName":"Last Name1" 
  } 
} 

 curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d @add.json http://127.0.0.1:8080/CXFEmployeeJsonRESTService/employeeservice/add


PUT a Resource: Updating an existing employee resource.
- Updating an existing employee record in the update.json file.
 { 
  "ns1.Employee":{ 
    "id":1, 
    "firstName":"Updated First Name1", 
    "lastName" :"Updated Last Name1" 
  } 
} 

 curl -v -H "Accept: application/json" -H "Content-type: application/json" -X PUT -d @update.json http://127.0.0.1:8080/CXFEmployeeJsonRESTService/employeeservice/update/

DELETE a Resource: Deleting an employee for a given id (id=2)
 curl -i -H "Accept: application/json" -X DELETE http://localhost:8080/CXFEmployeeJsonRESTService/employeeservice/delete/2/

Summary:
This tutorial looked at how we can create JSON RESTful Web Service using Apache CXF and test the services using CURL. You can find the sample code here.