Monday, February 18, 2013

Java API for JSON Processing (JSR 353) : JsonGenerator and JsonObjectBuilder

Java API for JSON Processing (JSR 353) cleared Public Review unanimously and is on its way to to standardization. There is still Proposed Final Draft and the final vote to come. As per the Java EE 7 schedule, the specification will be final on 4/15/2013. The implementation is already integrated in GlassFish 4 builds.

The API provides an Object Model (like DOM for XML) and Streaming API (like StAX for XML) to parse and generate JSON structure. Here is a table that provide code fragments for generating some common JSON:



JSONObject Model APIStreaming API
{ }JsonObject jsonObject =
     new JsonObjectBuilder().build();

new JsonWriter(System.out)
     .writeObject(jsonObject);
JsonGeneratorFactory factory =
     Json.createGeneratorFactory();

JsonGenerator gen =
     factory.createGenerator(System.out);

gen.writeStartObject().writeEnd();
{
  "apple":"red",
  "banana":"yellow"
}
new JsonObjectBuilder()
  .add("apple", "red")
  .add("banana", "yellow")
.build();
gen.writeStartObject()
     .write("apple", "red")
     .write("banana", "yellow")
   .writeEnd();
[
  { "apple":"red" },
  { "banana":"yellow" }
]
JsonArray jsonArray = new JsonArrayBuilder()
  .add(new JsonObjectBuilder()
          .add("apple","red"))

  .add(new JsonObjectBuilder()
          .add("banana","yellow"))

  .build();
gen.writeStartArray()
     .writeStartObject()
       .write("apple", "red")
     .writeEnd()
     .writeStartObject()
       .write("banana", "yellow")
     .writeEnd()
.writeEnd();
{
  "title":"The Matrix",
  "year":1999,
  "cast":[
    "Keanu Reaves",
    "Laurence Fishburne",
    "Carrie-Anne Moss"
  ]
}
new JsonArrayBuilder()
  .add(new JsonObjectBuilder()
  .add("title", "The Matrix")
  .add("year", 1999)
  .add("cast", new JsonArrayBuilder()
  .add("Keanu Reaves")
  .add("Laurence Fishburne")
  .add("Carrie-Anne Moss")))
.build();
gen.writeStartObject()
     .write("title", "The Matrix")
     .write("year", 1999)
     .writeStartArray("cast")
       .write("Keanu Reaves")
       .write("Laurence Fishburne")
       .write("Carrie-Anne Moss")
     .writeEnd()
   .writeEnd();

Sunday, February 17, 2013

Using Python Client with Java webservices (JAX-WS 2.0)

In this tutorial I am going to demonstrate you the development and deployment of the web service using Java JAX-WS API and consuming it with the help of the Python client.
Python provide many packages to support SOAP based web services,we will look one of them named suds to devlop our client.
Suds is a lightweight SOAP python client that provides a service proxy for Web Services.you can download suds from https://fedorahosted.org/suds/
installation of suds is pretty straightforward using fallowing methods
Here are the basic instructions for 3 different installation methods:

Using pip:
* Have the 'pip' package installed.
* Run 'pip install suds-jurko'.

Using easy-install:
* Have the 'distribute' package installed.
* Run 'easy_install suds-jurko'.

From sources:
* Unpack the source package somewhere.
* Run 'python setup.py install' from the source distribution's top level
folder.

Now come to the web service development using JAX-WS.
Step 1: create a dynamic webproject in eclipse.
Step 2: download the JAX-WS api from http://jax-ws.java.net/ after download unzip the binaries in a folder and look for the lib folder inside that,copy all the jars file inside the lib folder to our already created project's WEB-INF\lib folder
Step 3: create a bean with the name of IdealMatch inside the src folder as fallows:
package com.rajkrrsinghblogspot.beans;

import java.io.Serializable;

public class IdealMatch implements Serializable {
 
 private int age;
 private double salary;
 private String name;
 private String address;
 
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public double getSalary() {
  return salary;
 }
 public void setSalary(double salary) {
  this.salary = salary;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getAddress() {
  return address;
 }
 public void setAddress(String address) {
  this.address = address;
 }
 
}
Step 4:Now create your service interface and annotate it with @webservice and @webmethod annotations as fallows
package com.rajkrrsinghblogspot.ws.service;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

import com.rajkrrsinghblogspot.beans.IdealMatch;

@WebService
@SOAPBinding(style = Style.RPC)
public interface IdealMatchFinder {
 
 @WebMethod  IdealMatch findIdealMatch();
 

}

Step 5: provide the implementation for the service interface as shown
package com.rajkrrsinghblogspot.ws.service;

import javax.jws.WebService;

import com.rajkrrsinghblogspot.beans.IdealMatch;

@WebService(endpointInterface="com.rajkrrsinghblogspot.ws.service.IdealMatchFinder")
public class IdealMatchFinderImpl implements IdealMatchFinder {

 
 @Override
 public IdealMatch findIdealMatch() {
  System.out.println(":::::::: Ideal Match Finder criteria without args ::::::::");
  IdealMatch iMatch = new IdealMatch();
  iMatch.setName("Ajay Singh");
  iMatch.setAge(30);
  iMatch.setSalary(1000000);
  iMatch.setAddress("Noida");
  return iMatch;
 }

}

Step 6: create one file inside WEB-INF with the name of sun-jaxws.xml and configure it to provide end point,service name,implementation and url information.
<?xml version="1.0" encoding="UTF-8"?>

<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>
    <endpoint
        name='MatchFinder'
        implementation='com.rajkrrsinghblogspot.ws.service.IdealMatchFinderImpl'
        url-pattern='/findMatch'/>
</endpoints>

Step 7: now configure your web.xml to add listner WSServletContextListener
<?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_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>MatchMakerService</display-name>
  <listener>
        <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>MatchFinder</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>MatchFinder</servlet-name>
        <url-pattern>/findMatch</url-pattern>
    </servlet-mapping>
    
</web-app>

lets look at the project structure to check whether all components are in place:


Step 8: Now deploy the application on server and access the url http://localhost:8083/MatchMakerService/findMatch?wsdl

it means our service is up and running now we need to have a client to access this service,we are using python client in our application,lets create our python client.
Step 9: create your python client as fallows:
import suds

class Client:
    def __init__(self):
        self.client = suds.client.Client("http://localhost:8083/MatchMakerService/findMatch?wsdl")

    def get_ideal_match(self):
        return self.client.service.findIdealMatch()

    
if(__name__ == "__main__"):
    client = Client()
    idealMatch = client.get_ideal_match()
    print idealMatch
save it with the extension of .py and run using python command.After run you will find the service return on the shell