去年10月為了滿足一個客戶的需求,讓我開發(fā)一個教學(xué)博客系統(tǒng)出來,當(dāng)時考慮節(jié)約成本就使用了一個比較優(yōu)秀的開源博客平臺來做二次開發(fā)。這個開源平臺就是roller,是apache的一個項目,能收錄在apache下面說明還是有兩把刷子的,matrix的部落隔就是直接使用的roller,而且看到確切消息說網(wǎng)易的博客平臺也是基于roller進(jìn)行開發(fā)的。
roller地址:http://roller.apache.org/
現(xiàn)在教學(xué)博客平臺已近開發(fā)完成投入使用了,而在這個過程中發(fā)現(xiàn)了roller確實有很多地方值得一個jee開發(fā)人員借鑒的地方,所以今天開始打算把學(xué)到的這些經(jīng)驗進(jìn)行一下總結(jié)了。好久沒寫blog了,前段時間確實太忙了,事情太多了。現(xiàn)在打算每天擠點時間把這些經(jīng)驗都記錄下來,不然我怕日子久了我都忘記了。
首先先講的是xmlrpc,rpc的全稱是Remote Procedure Call,實際上就是為了讓客戶端可以輕松的對服務(wù)端的一些方法啊,過程進(jìn)行調(diào)用。xmlrpc其實是一個使用xml來實現(xiàn)rpc的規(guī)范,使用的傳輸協(xié)議還是我們最熟悉的http,不同的是傳輸?shù)母袷绞鞘褂脁ml的格式來封裝數(shù)據(jù)的,而不是使用html了。基于這個規(guī)范呢其實是有多種實現(xiàn)的,由php的,有Python的。在這里我要介紹的是roller中所使用的一個實現(xiàn),依然是apache下的一個項目Apache XML-RPC:http://ws.apache.org/xmlrpc/。
在roller中使用的是xmlrpc的服務(wù)段,所以下面我先介紹服務(wù)端和客戶端的設(shè)置以及調(diào)用方法
1、當(dāng)然是把Apache XML-RPC的包引入到服務(wù)端和客戶段
客戶端引入:xmlrpc-common.jar xmlrpc-client.jar
服務(wù)端引入:xmlrpc-common.jar xmlrpc-server.jar
2、使用java的實現(xiàn)當(dāng)然要有一個servlet了,
先介紹客戶端:遵循h(huán)ttp協(xié)議,客戶端針對一個url發(fā)送請求
下面是相關(guān)代碼
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
public class RpcClient {
public static void main(String[] args) throws Exception {
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
XmlRpcClient client = new XmlRpcClient();
try {
config.setServerURL(new URL("http://127.0.0.1:8088/roller-services/xmlrpc"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
config.setBasicUserName("user");
config.setBasicPassword("pwd");
config.setEnabledForExtensions(true);
config.setConnectionTimeout(60 * 1000);
config.setReplyTimeout(60 * 1000);
// set configuration
client.setConfig(config);
}
}
再介紹服務(wù)端:服務(wù)端自然要有一個servlet來接受這個請求了
在web.xml中配置servlet
<!--XmlRpc servlet-->
<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 for XML-RPC.</description>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>XmlRpcServlet</servlet-name>
<url-pattern>/roller-services/xmlrpc</url-pattern>
</servlet-mapping>
這里的配置我使用的是默認(rèn)的servlet,當(dāng)然你也可以使用自己定義的servlet了,我的需求比較簡單,所以就沒有再另外定義servlet
3、下面就是客戶端根據(jù)需求發(fā)送自己特定的rpc請求了,比如我需要獲取服務(wù)端所有的blogList
客戶端的調(diào)用代碼如下:
try {
Object[] result = (Object[]) client.execute("blogger.getAllblogList",
params);
} catch (Exception e) {
e.printStackTrace();
}
那么服務(wù)段又是如何處理這個請求的呢?上面那個servlet會把請求根據(jù)不同rpc請求轉(zhuǎn)發(fā)給不同的處理器,不過由于servlet我使用的是默認(rèn)的,所以分發(fā)這個動作是使用配置properties文件來實現(xiàn)的,這里有個不好的地方要說明的是配置文件必須在項目的/org/apache/xmlrpc/webserver/XmlRpcServlet.properties路徑下,這個是Apache XML-RPC做得不好的一個地方。配置文件內(nèi)容如下
blogger=org.apache.roller.webservices.xmlrpc.BloggerAPIHandler
metaWeblog=org.apache.roller.webservices.xmlrpc.MetaWeblogAPIHandler
當(dāng)服務(wù)端接受到上面客戶端的請求之后,就會根據(jù)blogger到BloggerAPIHandler去調(diào)用getAllblogList這個方法。
4 最后一步就是給客戶端回傳數(shù)據(jù)了
這里需要注意的是服務(wù)端一般使用的是Hashtable來對多個數(shù)據(jù)進(jìn)行封裝,比如:
Hashtable result = new Hashtable();
result.put("nickname", user.getUserName());
result.put("userid", user.getUserName());
result.put("email", "");
result.put("lastname", lastname);
result.put("firstname", firstname);
return result;
但是客戶端在解析的時候取出來的也是一個Hashtable,然后從中取出自己需要的數(shù)據(jù)了。
HashMap table = (HashMap) obj;
this.nickname = table.get("nickname").toString();
this.userid = table.get("userid").toString();
當(dāng)然,最好是做一個專門的解析類來對數(shù)據(jù)進(jìn)行解析了。
這里需要補(bǔ)充說明的是,Apache XML-RPC傳輸?shù)臄?shù)據(jù)類型是一些預(yù)先定義好的數(shù)據(jù)類型,但是同時它也支持用戶自定義的數(shù)據(jù)類型,
具體可以參見:http://ws.apache.org/xmlrpc/advanced.html
posted on 2008-07-17 07:23
rocket 閱讀(2223)
評論(8) 編輯 收藏 所屬分類:
經(jīng)驗積累 、
常用框架