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:
- 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.
- Create a new Dispatcher and register the handlers with it.
- 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:
- "echo" Echoes the first parameter value back to the client.
- "getDate" Returns the current date.
- "getTime" Returns the current time.
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.
- The client's host name.
- The client's IP address.
- Whether the request / notification was transmitted securely (e.g. via HTTPS).
- The client X.509 certificate principal, if authenticated.
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.
JSON-RPC 2.0 ServerWrite 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
- version 1.0 (2010-05-18)
- First release.
- version 1.1 (2010-10-10)
- Renames class RequestInfo to RequestContext.
- version 1.2 (2010-11-23)
- Renames package.
- Removes dependency on org.apache.commons.lang.
- version 1.3 (2011-03-05)
- Major API naming changes.
- Adds support for handling JSON-RPC 2.0 notifications.
- Allows for undefined (null) message context arguments in Dispatcher.dispatch() and {Request|Notification}Handler.process() methods.
- version 1.4 (2011-07-11)
- Raises minimal JSON-RPC 2.0 Base requirement to version 1.19.
- Adds support for reporting request processing time by adding a non-standard "_procTime" attribute to the JSON-RPC 2.0 response.
- version 1.4.1 (2011-07-15)
- Renames the non-standard processing time attribute to "xProcTime".
- Documentation improvements.
- version 1.5 (2012-02-20)
- Fixes a bug in MessageContext getter method for java.security.Principal.
- MessageContext allows storing of multiple java.security.Principal identities.
- Updates JSON-RPC 2.0 Base JAR to 1.25 (JSON Smart 1.1).
- version 1.5.1 (2012-04-03)
- Updates JSON-RPC 2.0 Base JAR to 1.25.1 (JSON Smart 1.1.1).
- version 1.6 (2012-07-14)
- Adds minimal MessageContext constructor.
- Updates JSON-RPC 2.0 Base JAR to 1.27.
- version 1.7 (2012-08-27)
- Dispatcher implements RequestHandler and Notification handler; deprecates Dispatcher.dispatch(...) methods.
- version 1.8 (2012-12-01)
- Upgrades JSON-RPC 2.0 Base JAR to 1.30.
- version 1.9 (2013-03-29)
- Switches project build from Ant to Maven.
- Upgrades to JSON-RPC 2.0 Base 1.34.
- version 1.9.1 (2013-03-30)
- Updates Maven pom.xml.
- version 1.9.2 (2013-04-02)
- Publishes library to Maven Central.
- version 1.10 (2013-04-09)
- Adds MessageContext(java.net.URLConnection) constructor.
- version 1.10.1 (2013-04-18)
- Updates scope for servlet 2.5 API dependency.
- version 1.11 (2015-03-16)
- Fixes potential NPE in MessageContext constructor.
- Cleans up code.
- Upgrades to JSON-RPC 2.0 Base 1.36.
- Upgrades to JSON Smart 1.3.1.