JSON-RPC 2.0 Server

  • Simple and efficient Java framework for processing
    JSON-RPC 2.0 requests and notifications
  • No complicated J2EE and Spring stuff,
    just POJOs
  • With message context passing

1. Simple server framework for processing JSON-RPC 2.0 requests

This is a simple and easy to understand "old-school" Java framework for processing JSON-RPC 2.0 requests and notifications. It consists of 2 classes and 2 interfaces only. You can use it as a starting point to write your own JSON-RPC 2.0 web service, HTTP servlet based or otherwise. Proven in several enterprise-grade applications, such as the Json2Ldap directory web service.

2. How does it work?

The JSON-RPC 2.0 server framework represents the classical handler pattern:

  1. Implement request and / or notification handlers for the various expected JSON-RPC 2.0 messages. A handler may process one or more request / notification methods identified by their name.
  2. Create a new Dispatcher and register the handlers with it.
  3. Pass the received JSON-RPC 2.0 requests and notifications to the Dispatcher.process(...) method. Then, if the message is a request, return the resulting JSON-RPC 2.0 response back to the client.

3. Requirements

The server framework itself requires the sister JSON-RPC 2.0 Base package to represent JSON-RPC 2.0 request, notification and response messages. The only other dependency is the JSON Smart library.

If you use Maven to build your project:

<dependency>
	<groupId>com.thetransactioncompany</groupId>
	<artifactId>jsonrpc2-server</artifactId>
	<version>{version}</version>
</dependency>

where {version} should be the latest stable.

4. Example

Here is an example program which demonstrates processing of three JSON-RPC 2.0 request methods:

Note that the handlers here are implemented as static nested classes. In real life applications it may be more suitable to declare the handlers as regular classes within their own source files.

// The JSON-RPC 2.0 Base classes that define the 
// JSON-RPC 2.0 protocol messages
import com.thetransactioncompany.jsonrpc2.*;

// The JSON-RPC 2.0 server framework package
import com.thetransactioncompany.jsonrpc2.server.*;

import java.text.*;
import java.util.*;


/**
 * Demonstration of the JSON-RPC 2.0 Server framework usage. The request
 * handlers are implemented as static nested classes for convenience, but in 
 * real life applications may be defined as regular classes within their old 
 * source files.
 *
 * @author Vladimir Dzhuvinov
 * @version 2011-03-05
 */ 
public class Example {


    // Implements a handler for an "echo" JSON-RPC method
    public static class EchoHandler implements RequestHandler {
	

        // Reports the method names of the handled requests
        public String[] handledRequests() {
		
            return new String[]{"echo"};
        }
		
		
         // Processes the requests
         public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) {
			
             if (req.getMethod().equals("echo")) {
				
                 // Echo first parameter
				
                 List params = (List)req.getParams();
	 
	         Object input = params.get(0);
	 
	         return new JSONRPC2Response(input, req.getID());
            }
            else {
	
                // Method name not supported
				
                return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
	    }
        }
    }
	
	
    // Implements a handler for "getDate" and "getTime" JSON-RPC methods
    // that return the current date and time
    public static class DateTimeHandler implements RequestHandler {
	
	
        // Reports the method names of the handled requests
	public String[] handledRequests() {
	
	    return new String[]{"getDate", "getTime"};
	}
	
	
	// Processes the requests
	public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) {
	
	    if (req.getMethod().equals("getDate")) {
	    
	        DateFormat df = DateFormat.getDateInstance();
		
		String date = df.format(new Date());
		
		return new JSONRPC2Response(date, req.getID());

            }
            else if (req.getMethod().equals("getTime")) {
	    
	        DateFormat df = DateFormat.getTimeInstance();
		
		String time = df.format(new Date());
		
		return new JSONRPC2Response(time, req.getID());
            }
	    else {
	    
	        // Method name not supported
		
		return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
            }
        }
    }
    
    
    public static void main(String[] args) {
	
        // Create a new JSON-RPC 2.0 request dispatcher
	Dispatcher dispatcher =  new Dispatcher();
	
	
	// Register the "echo", "getDate" and "getTime" handlers with it
	dispatcher.register(new EchoHandler());
	dispatcher.register(new DateTimeHandler());
	
	
	// Simulate an "echo" JSON-RPC 2.0 request
	List echoParam = new LinkedList();
	echoParam.add("Hello world!");
	
	JSONRPC2Request req = new JSONRPC2Request("echo", echoParam, "req-id-01");
	System.out.println("Request: \n" + req);
	
	JSONRPC2Response resp = dispatcher.process(req, null);
	System.out.println("Response: \n" + resp);
	
	// Simulate a "getDate" JSON-RPC 2.0 request
	req = new JSONRPC2Request("getDate", "req-id-02");
	System.out.println("Request: \n" + req);
	
	resp = dispatcher.process(req, null);
	System.out.println("Response: \n" + resp);
	
	// Simulate a "getTime" JSON-RPC 2.0 request
	req = new JSONRPC2Request("getTime", "req-id-03");
	System.out.println("Request: \n" + req);
	
	resp = dispatcher.process(req, null);
	System.out.println("Response: \n" + resp);
    }
}

The resulting console output:

Request: 
{"id":"req-id-01","method":"echo","params":["Hello world!"],"jsonrpc":"2.0"}
Response: 
{"id":"req-id-01","result":"Hello world!","jsonrpc":"2.0"}

Request: 
{"id":"req-id-02","method":"getDate","jsonrpc":"2.0"}
Response: 
{"id":"req-id-02","result":"Mar 5, 2011","jsonrpc":"2.0"}

Request: 
{"id":"req-id-03","method":"getTime","jsonrpc":"2.0"}
Response: 
{"id":"req-id-03","result":"3:20:47 PM","jsonrpc":"2.0"}

You can download the complete Java example from here.

5. Request + notification context info

The framework also includes a MessageContext class to allow passing of important context information about the processed request or notification to the handler.

6. Reporting request execution time

Since version 1.4 the Dispatcher is able to report request processing time in millisecond precision. Reporting is enabled by the Dispatcher.reportProcTime() method.

Once request execution time reporting is turned on, the dispatcher will append a non-standard "xProcTime" member to the resulting JSON-RPC 2.0 response.

Example:

{ 
   "result"    : "xyz",
   "id"        : 1,
   "jsonrpc"   : "2.0",
   "xProcTime" : "189 us"
}

The JSON-RPC 2.0 client can then parse the "xProcTime" metric to measure the performance of the service or to comparing hosting / cloud providers.

7. JavaDoc documentation

The JSON-RPC 2.0 Server source comes with extensive documentation in the form of JavaDocs. A copy of the docs is available for browsing online.

8. Download

The JSON-RPC 2.0 Server package comes with an Apache 2.0 open source license.

Download now JSON-RPC 2.0 Server

Write to me if you have questions or comments about the JSON-RPC 2.0 Server software. For general questions go to the JSON-RPC forum.

You may also want to have a look at the companion JSON-RPC 2.0 Shell product, a must have tool for developers undertaking serious JSON-RPC 2.0 work.

9. Change log