Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

JSON-RPC for Java

License

NotificationsYou must be signed in to change notification settings

0xwang-coder/jsonrpc4j

 
 

Repository files navigation

This project aims to provide the facility to easily implementJSON-RPC for the java programming language. jsonrpc4j uses theJackson library to convert javaobjects to and from json objects (and other things related toJSON-RPC).

JavadocDownloadTravis CIGitHub commitsMaintenance

Features Include:

  • Streaming server (InputStream \OutputStream)
  • HTTP Server (HttpServletRequest \HttpServletResponse)
  • Portlet Server (ResourceRequest \ResourceResponse)
  • Socket Server (StreamServer)
  • Integration with the Spring Framework (RemoteExporter)
  • Streaming client
  • HTTP client
  • Dynamic client proxies
  • Annotations support
  • Custom error resolving
  • Composite services

Maven

This project is built withMaven. Besure to check the pom.xml for the dependencies if you're not usingmaven. If you're already using spring you should have most (if not all)of the dependencies already - outside of maybe theJackson Library. Jsonrpc4j is availablefrom the maven central repo. Add the following to your pom.xml if you'reusing maven:

In<dependencies>:

<!-- jsonrpc4j--><dependency><groupId>com.github.briandilley.jsonrpc4j</groupId><artifactId>jsonrpc4j</artifactId><version>1.5.0</version></dependency>

If you want to just download the projects output JAR and it's dependencies you cando it over at theMaven repository.

JSON-RPC specification

The official source for theJSON-RPC 2.0 specification.The guys over atjson-rpc google groupseem to be fairly active, so you can ask clarifying questions there.

Streaming server and client

Jsonrpc4j comes with a streaming server and client to support applications of all types(not just HTTP). TheJsonRpcClient andJsonRpcServer have simple methodsthat takeInputStreams andOutputStreams. Also in the library is aJsonRpcHttpClientwhich extends theJsonRpcClient to add HTTP support.

Spring Framework

jsonrpc4j provides aRemoteExporter to expose java services as JSON-RPC over HTTP withoutrequiring any additional work on the part of the programmer. The following example explainshow to use theJsonServiceExporter within the Spring Framework.

Create your service interface:

packagecom.mycompany;publicinterfaceUserService {UsercreateUser(StringuserName,StringfirstName,Stringpassword);UsercreateUser(StringuserName,Stringpassword);UserfindUserByUserName(StringuserName);intgetUserCount();}

Implement it:

packagecom.mycompany;publicclassUserServiceImplimplementsUserService {publicUsercreateUser(StringuserName,StringfirstName,Stringpassword) {Useruser =newUser();user.setUserName(userName);user.setFirstName(firstName);user.setPassword(password);database.saveUser(user)returnuser;    }publicUsercreateUser(StringuserName,Stringpassword) {returnthis.createUser(userName,null,password);    }publicUserfindUserByUserName(StringuserName) {returndatabase.findUserByUserName(userName);    }publicintgetUserCount() {returndatabase.getUserCount();    }}

Configure your service in spring as you would any other RemoteExporter:

<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd">    <beanclass="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>    <beanid="userService"class="com.mycompany.UserServiceImpl">    </bean>    <beanname="/UserService.json"class="com.googlecode.jsonrpc4j.spring.JsonServiceExporter">        <propertyname="service"ref="userService"/>        <propertyname="serviceInterface"value="com.mycompany.UserService"/>    </bean></beans>

Your service is now available at the URL /UserService.json. Type conversion ofJSON->Java and Java->JSON will happen for you automatically. This service canbe accessed by any JSON-RPC capable client, including theJsonProxyFactoryBean,JsonRpcClient andJsonRpcHttpClient provided by this project:

<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <beanclass="com.googlecode.jsonrpc4j.spring.JsonProxyFactoryBean">        <propertyname="serviceUrl"value="http://example.com/UserService.json"/>        <propertyname="serviceInterface"value="com.mycompany.UserService"/>    </bean><beans>

In the case that your JSON-RPC requires named based parameters rather than indexedparameters an annotation can be added to your service interface (this also works onthe service implementation for the ServiceExporter):

packagecom.mycompany;publicinterfaceUserService {UsercreateUser(@JsonRpcParam(value="theUserName")StringuserName,@JsonRpcParam(value="thePassword")Stringpassword);}

By default all error message responses contain the the message as returned byException.getmessage() with a code of 0. This is not always desirable.jsonrpc4j supports annotated based customization of these error messages andcodes, for example:

packagecom.mycompany;publicinterfaceUserService {@JsonRpcErrors({@JsonRpcError(exception=UserExistsException.class,code=-5678,message="User already exists",data="The Data"),@JsonRpcError(exception=Throwable.class,code=-187)    })UsercreateUser(@JsonRpcParam(value="theUserName")StringuserName,@JsonRpcParam(value="thePassword")Stringpassword);}

The previous example will return the error code-5678 with the messageUser already exists if the service throws a UserExistsException. In thecase of any other exception the code-187 is returned with the valueofgetMessage() as returned by the exception itself.

Auto Discovery With Annotations

Spring can also be configured to auto-discover services and clients with annotations.

To configure auto-discovery of annotated services first annotate the service interface:

@JsonRpcService("/path/to/MyService")interfaceMyService {...servicemethods ...}

Next annotate the implementation of the service interface;

@AutoJsonRpcServiceImplclassMyServiceImpl {...servicemethods' implementations ...}

and use the following configuration to allow spring to find the implementation that you would like to expose:

<beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  <beanclass="com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter"/>  <beanclass="com.mycompany.MyServiceImpl" /></beans>

Configuring a client is just as easy:

<beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  <beanclass="com.googlecode.jsonrpc4j.spring.AutoJsonRpcClientProxyCreator">    <propertyname="baseUrl"value="http://hostname/api/" />    <propertyname="scanPackage"value="com.mycompany.services" />  </bean></beans>

Where thebaseUrl is added to the front of the path value provided by theJsonRpcService annotation andscanPackage tells spring which packagesto scan for services.

Without the Spring Framework

jsonrpc4j can be used without the spring framework as well. In fact, the clientand server both work in an Android environment.

Client

Here's an example of how to use the client to communicate with the JSON-RPC service described above:

JsonRpcHttpClientclient =newJsonRpcHttpClient(newURL("http://example.com/UserService.json"));Useruser =client.invoke("createUser",newObject[] {"bob","the builder" },User.class);

Or, the ProxyUtil class can be used in conjunction with the interface to create a dynamic proxy:

JsonRpcHttpClientclient =newJsonRpcHttpClient(newURL("http://example.com/UserService.json"));UserServiceuserService =ProxyUtil.createClientProxy(getClass().getClassLoader(),UserService.class,client);Useruser =userService.createUser("bob","the builder");

server

The server can be used without spring as well:

// create itJsonRpcServerserver =newJsonRpcServer(userService,UserService.class);

After having created the server it's simply a matter of calling one of thehandle(...) methods available. For example, here's a servlet using thevery sameUserService:

classUserServiceServletextendsHttpServlet {privateUserServiceuserService;privateJsonRpcServerjsonRpcServer;protectedvoiddoPost(HttpServletRequestreq,HttpServletResponseresp) {jsonRpcServer.handle(req,resp);    }publicvoidinit(ServletConfigconfig) {//this.userService = ...this.jsonRpcServer =newJsonRpcServer(this.userService,UserService.class);    }}

Composite Services

Multiple services can be combined into a single server using one of theProxyUtil::createCompositeService(...) methods. For example:

UserverServiceuserService = ...;ContentServicecontentService = ...;BlackJackServiceblackJackService = ...;ObjectcompositeService =ProxyUtil.createCompositeServiceProxy(this.getClass().getClassLoader(),newObject[] {userService,contentService,blackJackService},newClass<?>[] {UserService.class,ContentService.class,BlackJackService.class},true);// now compositeService can be used as any of the above service, ie:Useruser = ((UserverService)compositService).createUser(...);Contentcontent =  ((ContentService)compositService).getContent(...);Handhand = ((BlackJackService)compositService).dealHand(...);

This can be used in conjunction with theJsonRpcServer to expose the servicemethods from all services at a single location:

JsonRpcServerjsonRpcServer =newJsonRpcServer(compositeService);

A spring service exporter exists for creating composite services as wellnamedCompositeJsonServiceExporter.

Streaming (Socket) Server

A streaming server that usesSockets is available in the form of theStreamServer class. It's use is very straightforward:

// create the jsonRpcServerJsonRpcServerjsonRpcServer =newJsonRpcServer(...);// create the stream serverintmaxThreads =50;intport =1420;InetAddressbindAddress =InetAddress.getByName("...");StreamServerstreamServer =newStreamServer(jsonRpcServer,maxThreads,port,bindAddress);// start it, this method doesn't blockstreamServer.start();

and when you're ready to shut the server down:

// stop it, this method blocks until// shutdown is completestreamServer.stop();

Of course, this is all possible in the Spring Framework as well:

    <beanid="streamingCompositeService"class="com.googlecode.jsonrpc4j.spring.CompositeJsonStreamServiceExporter"><!-- can be an IP, hostname or omitted to listen on all available devices-->        <propertyname="hostName"value="localhost"/>        <propertyname="port"value="6420"/>        <propertyname="services">        <list>        <refbean="userService" />        <refbean="contentService" />        <refbean="blackJackService" />        </list>        </property>    </bean>

JsonRpcServer settings explained

The following settings apply to both theJsonRpcServer andJsonServiceExporter:

  • allowLessParams - Boolean specifying whether or not the server should allow for methods to be invoked by clients supplying less than the required number of parameters to the method.
  • allowExtraParams - Boolean specifying whether or not the server should allow for methods to be invoked by clients supplying more than the required number of parameters to the method.
  • rethrowExceptions - Boolean specifying whether or not the server should re-throw exceptions after sending them back to the client.
  • backwardsComaptible - Boolean specifying whether or not the server should allow for jsonrpc 1.0 calls. This only includes the omission of the jsonrpc property of the request object, it will not enable class hinting.
  • errorResolver - An implementation of theErrorResolver interface that resolves exception thrown by services into meaningful responses to be sent to clients. MultipleErrorResolvers can be configured using theMultipleErrorResolver implementation of this interface.

Server Method resolution

Methods are resolved in the following way, each step immediately short circuits theprocess when the available methods is 1 or less.

  1. All methods with the same name as the request method are considered
  2. IfallowLessParams is disabled methods with more parameters than the request are removed
  3. IfallowExtraParams is disabled then methods with less parameters than the request are removed
  4. If either of the two parameters above are enabled then methods with the lowest difference in parameter count from the request are kept
  5. Parameters types are compared to the request parameters and the method(s) with the highest number of matching parameters is kept
  6. If there are multiple methods remaining then the first of them are used

jsonrpc4j's method resolution allows for overloaded methodssometimes. Primitives areeasily resolved from json to java. But resolution between other objects are not possible.

For example, the following overloaded methods will work just fine:

json request:

{"jsonrpc":"2.0","id":"10","method":"aMethod","params":["Test"]}

java methods:

publicvoidaMethod(Stringparam1);publicvoidaMethod(Stringparam1,Stringparam2);publicvoidaMethod(Stringparam1,Stringparam2,intparam3);

But the following will not:

json request:

{"jsonrpc":"2.0","id":"10","method":"addFriend","params":[{"username":"example","firstName":"John"}]}

java methods:

publicvoidaddFriend(UserObjectuserObject);publicvoidaddFriend(UserObjectExuserObjectEx);

The reason being that there is no efficient way for the server todetermine the difference in the json between theUserObjectandUserObjectEx Plain Old Java Objects.

Custom method names

In some instances, you may need to expose a JsonRpc method that is not a valid Java method name.In this case, use the annotation @JsonRpcMethod on the service method.

@JsonRpcService("/jsonrpc")publicinterfaceLibraryService {@JsonRpcMethod("VideoLibrary.GetTVShows")List<TVShow>fetchTVShows(@JsonRpcParam(value="properties")finalList<String>properties);}
{"jsonrpc":"2.0","method":"VideoLibrary.GetTVShows","params": {"properties": ["title"] },"id":1}

About

JSON-RPC for Java

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java100.0%

[8]ページ先頭

©2009-2025 Movatter.jp