RPC in Javascript using JSON-RPC-Java

Remote procedure call (RPC) in javascript is a great concept of creating rich web applications. First we will see some background about RPC using JavaScript Object Notation (JSON).

See following quote from Wikipedia entry of JSON-RPC.

JSON-RPC is a remote procedure call protocol encoded in JSON. It is a very simple protocol (and very similar to XML-RPC), defining only a handful of data types and commands. In contrast to XML-RPC or SOAP, it allows for bidirectional communication between the service and the client, treating each more like peers and allowing peers to call one another or send notifications to one another. It also allows multiple calls to be sent to a peer which may be answered out of order.

A JSON invocation can be carried on an HTTP request where the content-type is application/json. Besides using HTTP for transport, one may use TCP/IP sockets. Using sockets, one can create much more responsive web applications with JSON-RPC, compared to polling data from a service with JSON-RPC over HTTP.

SON-RPC-Java is a key piece of Java web application middleware that allows JavaScript DHTML web applications to call remote methods in a Java Application Server without the need for page reloading (now referred to as AJAX). It enables a new breed of fast and highly dynamic enterprise Web 2.0 applications.
For using JSON-RPC-Java in your code, you need to download following json-rpc-java-1.0.1.zip file and unzip it.

http://oss.metaparadigm.com/jsonrpc/download.html

The zip contains required jsonrpc-1.0.jar and jsonrpc.js files that we will use in our project.

Once the JAR file is in classpath of your project, modify your WEB.XML (deployment descriptor) file and make an entry for JSONRPCServlet as follow.


<servlet>
<servlet-name>com.metaparadigm.jsonrpc.JSONRPCServlet</servlet-name>
<servlet-class>com.metaparadigm.jsonrpc.JSONRPCServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>com.metaparadigm.jsonrpc.JSONRPCServlet</servlet-name>
<url-pattern>/JSON-RPC</url-pattern>
</servlet-mapping>

Note that JSONRPCServlet is a servlet class inside the jsonrpc-1.0.jar file. Also, we have mapped a URL /JSON-RPC with the servlet. Hence the servlet will be invoked by the container whenever this URL is called by the client.

Also, do not forget in include the javascript file in your application.

<script src="js/jsonrpc.js"type="text/javascript"></script>
We will create a small webpage which will have two textboxes to enter numbers and a button which will call the RPC (call .sum() method on an object which resides in server) and send these two numbers to server. Server will do sum of these numbers and return the result back and the result will be displayed on webpage.
Following is the content of the html page.
<html>
<head>
<title>JSON-RPC-Java Demo</title>
<script type="text/javascript" src="js/jsonrpc.js"></script>
<script type="text/javascript">
function fnSum(form) {
try {
//Create a jsonrpc object for doing RPC.
jsonrpc = new JSONRpcClient("JSON-RPC");

// Call a Java method on the server
result = jsonrpc.sumObject.sum(form.a.value, form.b.value);
//Display the result
alert(result);

} catch(e) {
alert(e.description);
}
}
</script>
</head>
<body>
<h1>JSON-RPC-JAVA</h1>
<form>
<input type="text" name="a"/>
<input type="text" name="b"/>
<input type="button" onclick="fnSum(this.form)" value="Sum"/>
</form>
</body>
</html>

Note that in order to use JSON-RPC-Java, you need to set an object of com.metaparadigm.jsonrpc.JSONRPCBridge class in session. All the object that we will use in RPC from Client side needs to be registered into JSONRPCBridge’s object. JSONRPCBridge object can be written in session using jsp:useBean tag.

   <jsp:useBean id="JSONRPCBridge" scope="session"
   class="com.metaparadigm.jsonrpc.JSONRPCBridge" />

We will use a business class called Sum which will do sum operation on the input and return the output. Following is the content of Sum class.

package com.javamagic.jsonrpc;
public class Sum {
public Integer sum(Integer a, Integer b) {
return a + b;
}
}

Thus we need to register an object of class Sum in JSONRPCBridge object in order to use it from javascript.


Sum sumObject = new Sum();
JSONRPCBridge.registerObject("sumObject", sumObject);

Doing RPC from javascript is easy now. All we need is an jsonrpc object that we get by doing jsonrpc = new JSONRpcClient(“JSON-RPC”);. Note that the argument passed inside the JSONRpcClient() is the URL that we mapped to JSONRPCServlet servlet.
Once we get an object of jsonrpc, we can call remote methods by:


result = jsonrpc.sumObject.sum(form.a.value, form.b.value);

Where sumObject is the name that we provided while registering Sum class to JSONRPCBridge.

Following is the screenshot of the html page for user input.

Following is the sum output that the server returned to webpage using json-rpc.

Hope you will like this. Cheers… 🙂

Advertisements

Creating & Parsing JSON data with Java Servlet/Struts/JSP

JSON (JavaScript Object Notation) is a lightweight computer data interchange format. It is a text-based, human-readable format for representing simple data structures and associative arrays (called objects). The JSON format is specified in RFC 4627 by Douglas Crockford. The official Internet media type for JSON is application/json.

The JSON format is often used for transmitting structured data over a network connection in a process called serialization. Its main application is in AJAX web application programming, where it serves as an alternative to the traditional use of the XML format.

Supported data types

  1. Number (integer, real, or floating point)
  2. String (double-quoted Unicode with backslash escapement)
  3. Boolean (true and false)
  4. Array (an ordered sequence of values, comma-separated and enclosed in square brackets)
  5. Object (collection of key/value pairs, comma-separated and enclosed in curly brackets)
  6. null

Syntax

The following example shows the JSON representation of an object that describes a person. The object has string fields for first name and last name, contains an object representing the person’s address, and contains a list of phone numbers (an array).

{
"firstName": "John",
"lastName": "Smith",
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": 10021
},
"phoneNumbers": [
"212 732-1234",
"646 123-4567"
]
}

Creating JSON data in Java
JSON.org has provided libraries to create/parse JSON data through Java code. These libraries can be used in any Java/J2EE project including Servlet, Struts, JSF, JSP etc and JSON data can be created.

Download JAR file json-rpc-1.0.jar (75 kb)

Use JSONObject class to create JSON data in Java. A JSONObject is an unordered collection of name/value pairs. Its external form is a string wrapped in curly braces with colons between the names and values, and commas between the values and names. The internal form is an object having get() and opt() methods for accessing the values by name, and put() methods for adding or replacing values by name. The values can be any of these types: Boolean, JSONArray, JSONObject, Number, and String, or the JSONObject.NULL object.

import org.json.JSONObject;

...
...

JSONObject json = new JSONObject();
json.put("city", "Mumbai");
json.put("country", "India");

...

String output = json.toString();

...

Thus by using toString() method you can get the output in JSON format.

JSON Array in Java

A JSONArray is an ordered sequence of values. Its external text form is a string wrapped in square brackets with commas separating the values. The internal form is an object having get and opt methods for accessing the values by index, and put methods for adding or replacing values. The values can be any of these types: Boolean, JSONArray, JSONObject, Number, String, or the JSONObject.NULL object.

The constructor can convert a JSON text into a Java object. The toString method converts to JSON text.

JSONArray class can also be used to convert a collection of Java beans into JSON data. Similar to JSONObject, JSONArray has a put() method that can be used to put a collection into JSON object.

Thus by using JSONArray you can handle any type of data and convert corresponding JSON output.

Using json-lib library

JSON-lib is a java library for transforming beans, maps, collections, java arrays and XML to JSON and back again to beans and DynaBeans.

Json-lib comes in two flavors, depending on the jdk compatibility. json-lib-x.x-jdk13 is compatible with JDK 1.3.1 and upwards. json-lib-x.x-jdk15 is compatible with JDK 1.5, includes support for Enums in JSONArray and JSONObject.

Download: json-lib.jar

Json-lib requires (at least) the following dependencies in your classpath:

  1. jakarta commons-lang 2.5
  2. jakarta commons-beanutils 1.8.0
  3. jakarta commons-collections 3.2.1
  4. jakarta commons-logging 1.1.1
  5. ezmorph 1.0.6

Example

package net.javamagic.java;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

public class JsonMain {
public static void main(String[] args) {

Map<String, Long> map = new HashMap<String, Long>();
map.put("A", 10L);
map.put("B", 20L);
map.put("C", 30L);

JSONObject json = new JSONObject();
json.accumulateAll(map);

System.out.println(json.toString());

List<String> list = new ArrayList<String>();
list.add("Sunday");
list.add("Monday");
list.add("Tuesday");

json.accumulate("weekdays", list);
System.out.println(json.toString());
}
}

Output:

{"A":10,"B":20,"C":30}
{"A":10,"B":20,"C":30,"weekdays":["Sunday","Monday","Tuesday"]}

Using Google Gson library

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.

There are a few open-source projects that can convert Java objects to JSON. However, most of them require that you place Java annotations in your classes; something that you can not do if you do not have access to the source-code. Most also do not fully support the use of Java Generics. Gson considers both of these as very important design goals.

Gson Goals

  • Provide simple toJson() and fromJson() methods to convert Java objects to JSON and vice-versa
  • Allow pre-existing unmodifiable objects to be converted to and from JSON
  • Extensive support of Java Generics
  • Allow custom representations for objects
  • Support arbitrarily complex objects (with deep inheritance hierarchies and extensive use of generic types)

Google Gson Example


import java.util.List;
import com.google.gson.Gson;

public class Test {

public static void main(String... args) throws Exception {
String json =
"{"
+ "'title': 'Computing and Information systems',"
+ "'id' : 1,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Level one CIS',"
+ "'id' : 2,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Intro To Computing and Internet',"
+ "'id' : 3,"
+ "'children': 'false',"
+ "'groups':[]"
+ "}]"
+ "}]"
+ "}";

// Now do the magic.
Data data = new Gson().fromJson(json, Data.class);

// Show it.
System.out.println(data);
}

}

class Data {
private String title;
private Long id;
private Boolean children;
private List<Data> groups;

public String getTitle() { return title; }
public Long getId() { return id; }
public Boolean getChildren() { return children; }
public List<Data> getGroups() { return groups; }

public void setTitle(String title) { this.title = title; }
public void setId(Long id) { this.id = id; }
public void setChildren(Boolean children) { this.children = children; }
public void setGroups(List<Data> groups) { this.groups = groups; }

public String toString() {
return String.format("title:%s,id:%d,children:%s,groups:%s", title, id, children, groups);
}

Hope this will help you.  Cheers… 🙂