Showing posts with label xml-rpc. Show all posts
Showing posts with label xml-rpc. Show all posts

Thursday, April 10, 2008

A Simple Web 2.0 Framework

I have completed a simple application which supports common web 2.0 features: rating, commenting, tagging.
Demo address is: http://156.56.104.196:8080/tagService/index_ui.html.

The basic unit in my system is called record. A record is abstraction of an object. Theoretically, it can be of any type: image, text, presentation... However, the key issue is how to present different types of records to end users. Text is easy to present and it can be displayed to users directly. For image, img element can be used but it requires that the image be stored somewhere on the website so that it can be accessed by visiting a URL. Currently, only text is supported. When a user retrieves some record, text content of that record is displayed directly in browser.

Operations:
(1) Add a new record
Users add a new record by uploading a file to server and specifying name, description and tags. Then a unique id is generated for this new record at server side.
(2) List all records
Get all records in the system.
(3) Get a record based on its id
According to record id, get corresponding id.
(4) Get records according to tag
According to user-specified tag, corresponding records are returned. Currently, users can only specify a single tag.
(5) Post comment and rating of a certain record
Users can post comments and ratings about records.
(6) Comment and rating of comment.
Besides comments of records, comments of comments are supported. It means that users can post comments about existing comments besides records.

Architecture:
web20_arch_ws 
Client sends request to a server which uses servlet to handles it. Then the servlet accesses a web service which provides web 2.0 functionalities.

Presentation location:
What is stored in backend database is raw data. And it does not contain information about how to present it to end users. E.g. layout, font-size...
There are two strategies to transform raw data into final presentation data: server-side servlet and client-side javascript.
(1) Server-side servlet

web20_arch_html_ws
When servlet responds to user's request, a HTML document is returned. The HTML document does not only contains data but also contains presentation information. So it can be displayed directly. In this method, servlet formats the raw data received from web service into a corresponding HTML document.

(2) Client-side javascript

web20_arch_json_ws 
In this method, servlet just returns raw data in JSON format. It means returned data does not contain any presentation information. And client side javascript displays the raw data in a specific manner. Actually, to use this method, AJAX should be used. Object XmlHttpRrequest can be used to make asynchronous request without refreshing whole page.

Personally, I prefer the second method.
I remember there are some server-side Java libraries which can be used to make transformation execute with ease.

AJAX
    AJAX is used frequently. However, the format of request is not XML. I manually compose POST query in Javascript and then send it by using XmlHttpRequest. Actually, I use application/x-www-form-urlencoded which is the default data encoding of form submission. I chose this encoding because it is simple compared to the other encoding - multipart/form-data. To make it work well, the data must be escaped.
    Responses from server are in JSON format. So javascript decodes JSON string and dynamically modifies web page accordingly.
    An alternative method is to use XML-RPC.

Possible future work:
(1) User management
Currently, the system is open and everyone can use it anonymously.
(2) RESTful access
(3) Support image type in presentation layer.
(4) Persistence of server data.

Tuesday, October 23, 2007

XML-RPC Usage

Currently, I am focusing on building client and server programs which communicate with each other by using XML-RPC.
Client
To support XML-RPC at client side, there are two choices. I write javascript functions that handle XML-RPC related stuff --encoding, decoding, escape ... I read the XML-RPC specification. It is not long, just a few pages. However, to implement a robust and steady xml-rpc javascript library is not so easy as it looks. I don't have so much time to do this. So, I chose to make use of existing library. I surveyed many XML-RPC javascript libraries. Shortly afterwards, I found that most of the libraries were not satisfying. For example, some libraries even don't escape the parameters passed to a method. If a parameter is a string and it contains '<' characters, those '<' characters must be escaped in order not to confuse the server because '<' marks start of a tag!! After trying lots of times, I found two good libraries. One is mozilla xml-rpc javascript library which is used by Firefox. However, it requires additional javascript libraries which are basis of Firefox javascript libraries. To use it, lots of libraries are needed and obviously this is cumbersome.  The other good library is Javascript O Lait which builds generic architecture to allow users to create and import module. In addition to support of modularity, it provides many useful modules, such as Codec, JSON-RPC, XML-RPC, String extension ... At last I decided to use Jsolait. Key code is:
var url = "http://127.0.0.1:8080/sample/xmlrpc";//The path must comply with configuration at server side
var methods = ["zhguo.handler.inBound"];//This is the full qualified name of the method you want to invoke. 
     //Note: this must comply with the configuration at service side
var xmlrpc=null;
try{
    xmlrpc = imprt("xmlrpc"); //import the needed module
}catch(e){
    throw "importing of xmlrpc module failed.";
}
 
try{
 var service = new xmlrpc.ServiceProxy( url, methods );
 var from = "home", to = "rpc";
 service.zhguo.handler.inBound( from, to );//directly call the method by using service object
}catch(e){
 alert( e );
} 
Server

I make use of Apache XML-RPC Java library. There is no detailed document on the web. Official website has some description on how to quickly build application based on XML-RPC. There are several ways you can use the XML-RPC service. I chose to embed it in Tomcat container. Key procedure is:
(1) Edit the web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   version="2.5">
  <display-name>Test for XML-RPC</display-name>
  <description>This is a test for XML-RPC</description>
 <servlet>
  <servlet-name>XmlRpcServlet</servlet-name>
  <servlet-class>org.apache.xmlrpc.webserver.XmlRpcServlet</servlet-class>
  <init-param>
   <param-name>enabledForExtensions</param-name>
   <param-value>true</param-value>
   <description>Sets, whether the servlet supports vendor extensions.</description>
  </init-param>
 </servlet> 
 <servlet-mapping>
  <servlet-name>XmlRpcServlet</servlet-name>
  <url-pattern>/xmlrpc</url-pattern>
 </servlet-mapping>
</web-app>
(2) Create your service. My sample class is:
package zhguo.test;
public class SimpleHandler{
 public SimpleHandler(){}
 public String inBound( String from, String to ){
  return "thank you, " + from +", for calling " + to;
 }
}
And put the corresponding .class file in the directory WEB-INF/classes/zhguo/test/.
(3) Add a file called XmlRpcServlet.properties under directory WEB-INF/classes/org/apache/xmlrpc/webserver/. Content of the file is
zhguo.handler=zhguo.test.SimpleHandler
Note: zhguo.test.SimpleHandler is the class which provides service to XML-RPC client. The public functions in this class are exposed by Apache XML-RPC framework to clients. In other words, clients can invoke public functions defined in class zhguo.test.SimpleHandler. The property name is an arbitrary string. It represents the corresponding service class (In this case it is zhguo.test.SimpleHandler). Clients use this name to access the service. So, in javascript above, one statement is 'var methods = ["zhguo.handler.inBound"]'. Upon receiving the request, the server looks up the class corresponding to "zhguo.handler", invokes inBound function of that class and returns the result.
(4) Put the necessary libraries(XML-RPC .jar files) in the lib directory
(5) Starts the tomcat.
Finally, the directory layout is:
WEB-INF/lib/
WEB-INF/classes/org/apache/xmlrpc/webserver/XmlRpcServlet.properties
WEB-INF/classes/zhguo/test/SimpleHandler.class
WEB-INF/web.xml