Overview of the RPC adapter libraries
Web-remoting is a pattern that provides support for JavaScriptTM or client-side code to directly invoke server side logic. This pattern provides
the ability to invoke JavaTM methods from JavaScript. The invocation is by means of a JSON-RPC call. The most common usage is asynchronous calls
with XmlHttpRequest. Data is transferred between the server and client in JSON format. Therefore, this pattern is essentially a form of JSON Web services.
Introducing the RPC adapter
IBM® implementation for Web remoting is referred to as the RPC adapter for IBM. The RPC adapter is designed to help developers create command-based services
quickly and easily in a manner that complements programming styles for Ajax applications and other lightweight clients. Implemented as a generic servlet,
the RPC adapter provides an HTTP interface to registered JavaBeans.
The RPC adapter currently supports two RPC protocols:
- HTTP RPC, which encodes RPC invocations as URLs with query parameters, for HTTP GET, or form parameters, for HTTP POST.
- JSON-RPC, supports the Simple Method Description(SMD) service descriptor employed by the Dojo dojo.rpc.JsonService API.
HTTP RPC
In HTTP RPC, invocations are made using URLs with query parameters or form parameters.
The RPC adapter intercepts and deserializes the URL to get service name, method name, and input parameters.
Using these information RPC adapter invokes the corresponding method of matching JavaBeans.
For example, clients can invoke test.Example.getEcho("Hello world")
on the following JavaBeans:
package test;
public class Example {
public String getEcho(String message) {
return(message);
}
}
Invoke the test.Example.getEcho("Hello world")
through HTTP RPC using HTTP GET as follows:
GET /contextRoot/RPCAdapter/httprpc/example/echo?p0=Hello%20world HTTP/1.1
All these calls have to be made after you have properly configured RPC adapter to work with your application.
For this correct configuration, you need to add the RPCAdapter Java archive (JAR) file to WEB-INF/lib of your WAR file, make the following entries in the web.xml file.
RPCAdapter
RPCAdapter
com.ibm.websphere.rpcadapter.RPCAdapter
RPCAdapter
/RPCAdapter
RPCAdapter
/RPCAdapter/*
Specify a RpcAdapterConfig.xml file in the WEB-INF directory. This file is used to configure the services that are exported. In this case, a sample RpcAdapterConfig.xml file is similar to the following example:
xml
Sample
test.pojo.Sample
The derived HTTP RPC API assigns p0 as the name of the first argument. This default behavior is due to current limitations in the Java reflection APIs. Meaningful parameter names can be assigned with bean descriptor information or by means of specifying parameter names in the RpcAdapterConfig.xml file. For example, look at getEcho() in this bean:
package test;
import com.ibm.websphere.rpcadapter.SelfBeanInfo;
public class Example2 implements SelfBeanInfo {
public String getEcho(String message) {
return(message);
}
public static String[][] getBeanDescriptorInfo() {
String [][] mds = {
{"method", "getEcho", "Echoes the input String.", "GET", "message", "String to be echoed."},
};
return(mds);
}
}
The above example can be invoked as:
GET /contextRoot/httprpc/example/echo?message=Hello%20world HTTP/1.1
package test;
public class Example2 {
public String getEcho(String message) {
return(message);
}
}
The above example can be invoked as:
GET /contextRoot/httprpc/example/echo?message=Hello%20world HTTP/1.1
with the following RpcAdapterConfig.xml.
xml
example
test.pojo.Example2
echo
echos the message
message
Contains the message to be echo'd.
The default-format element in the configuration file specifies the default format to be used when format is not specified in the request. This format can be either XML or JSON.
JSON-RPC
In JSON-RPC, method invocation is made using JSON objects. The response generated is also a JSON object. The registered JavaBeans can be accessed through the Dojo JSON-RPC API:
var example = new dojo.rpc.JsonService("/contextRoot/RPCAdapter/jsonrpc/example");
example.getEcho('Hello world').addCallback(exampleCallback);
function exampleCallback(result) {
// response is available as result.getEchoReturn.String
}
Specifying the bean descriptor information
In RPC adapter, use the bean descriptor information to specify information about the JavaBeans that are available.
If you do not specify a bean descriptor, then the information is obtained by way of reflection. You can
specify the bean descriptor information in two ways. Consider the JavaBeans called Sample shown below.
package test.pojo;
import java.util.List;
import java.util.Vector;
/**
* Example showing custom Bean access specified with a separate BeanInfo class.
* This sample is instructive for cases where the Bean class cannot be modified.
*
* @see test.pojo.SampleBeanInfo
* @see test.pojo.SampleNoBeanInfo
* @see test.pojo.SampleSelfBeanInfo
*/
public class Sample {
/**
* Echoes the input String. This stateless operation works correctly
* regardless of the setting of the bean descriptor oneInstancePerUser
.
*
* @param message String to be echoed.
*/
public String echo(String message) {
return(message);
}
public String echoNoArg() {
return("Hello World");
}
public boolean echoBoolean(boolean b) {
return(b);
}
public boolean echoIntegerBean(boolean b) {
return(b);
}
List _values = new Vector();
/**
* Adds a value to a list that can be retrieve with the getValues
method.
* This stateful scenario requires that the bean descriptor oneInstancePerUser
* be set to true.
*
* @param value String added to the list.
*/
public void addValue(String value) {
_values.add(value);
}
/**
* Returns the cumulative list of values added with the addValue
method.
* This stateful scenario requires that the bean descriptor oneInstancePerUser
* be set to true.
*
* @return List of Strings previously added to the list.
*/
public List getValues() {
return(_values);
}
}
You can create a BeanInfo object called SampleBeanInfo to describe the Sample JavaBeans. Note how the
BeanInfo class has SimplerBeanInfo as its parent. Also note that you need to call setBeanClass in the constructor with Sample.class as the parameter.
package test.pojo;
import com.ibm.websphere.rpcadapter.SimplerBeanInfo;
/**
* Example BeanInfo class showing declarative-type descriptor information
* supported by the RPC adapter.
*
* @see test.pojo.Sample
*/
public class SampleBeanInfo extends SimplerBeanInfo {
/**
* SimplerBeanInfo uses Java Reflection; must set the Bean class first.
*/
public SampleBeanInfo() {
setBeanClass(Sample.class);
}
public String[][] getBeanDescriptorInfo() {
String [][] mds = {
{"bean", "oneInstancePerUser", "true"},
{"method", "echo", "Echoes the input String.", "GET", "message", "String to be echoed."},
{"method", "echoNoArg", "Echoes Hello World.", "GET" },
{"method", "addValue", "Adds a value to a list.", "GET", "value", "value to add"},
{"method", "getValues", "Returns the list.", "GET"},
{"method", "echoBoolean", "Echoes a boolean value.", "GET", "b", "Boolean to be echoed."},
};
return(mds);
}
}
Another way to specify the bean descriptor is to include the bean descriptor information in the bean class itself. Note that the bean class implements the SelfBeanInfo interface. It should also have a static method getBeanDescriptorInfo() that returns information on the JavaBeans.
package test.pojo;
import java.util.List;
import java.util.Vector;
import com.ibm.websphere.rpcadapter.SelfBeanInfo;
/**
* Example showing custom Bean access specified with embedded descriptive
* information. This sample is instructive for cases where the Bean can be
* modified.
*
* @see test.pojo.SampleNoBeanInfo
* @see test.pojo.Sample
*/
public class SampleSelfBeanInfo implements SelfBeanInfo {
/**
* Echoes the input String. This stateless operation works correctly
* regardless of the setting of the bean descriptor oneInstancePerUser
.
*
* @param message String to be echoed.
*/
public String echo(String message) {
return(message);
}
List _values = new Vector();
/**
* Adds a value to a list that can be retrieve with the getValues
method.
* This stateful scenario requires that the bean descriptor oneInstancePerUser
* be set to true.
*
* @param value String added to the list.
*/
public void addValue(String value) {
_values.add(value);
}
/**
* Returns the cumulative list of values added with the addValue
method.
* This stateful scenario requires that the bean descriptor oneInstancePerUser
* be set to true.
*
* @return List of Strings previously added to the list.
*/
public List getValues() {
return(_values);
}
public static String[][] getBeanDescriptorInfo() {
String [][] mds = {
{"bean", "oneInstancePerUser", "true"},
{"method", "echo", "Echoes the input String.", "GET", "message", "String to be echoed."},
{"method", "addValue", "Adds a value to a list.", "GET", "value", "value to add"},
{"method", "getValues", "Returns the list.", "GET"},
};
return(mds);
}
}
An important thing to note is that there should be no BeanInfo class in the classpath if you don't want to use BeanInfo. This is because the RPC adapter checks for BeanInfo classes by adding BeanInfo to the POJO class name and then tries to load that information first.
You also need to register the objects you need to expose in the RPCAdapterConfig.xml irrespective of whether you use BeanDescriptors or not.
Package structure
This library is distributed in a stand-alone version:
Stand-alone package
This package is organized in the
following
manner
For WebSphere® Application Server V8.5
|
<install_root>/optionalLibraries/web2mobile/rpcAdapter/RPCAdapter.jar
|
The Java class files
packaged in a Java archive (JAR) format that
implement the API. |
|