本文為原創,如需轉載,請注明作者和出處,謝謝!
jabsorb是一種基于Ajax/Web 2.0的簡單輕便的框架,可用于在Web瀏覽中通過HTTP請求向服務端發送請求,并獲得響應數據。實際上jabsorb就是json的升級版(不僅改了個名,而且包名都改了),目前最新版本是1.3。
老版本的json可以從http://oss.metaparadigm.com/jsonrpc/download.html下載。
jabsorb可以從http://jabsorb.org/Download下載。
jabsorb在json基礎上有了很大的改進,從1.2版開始支持ORB和循環引用(Circular References)。使用jabsorb至少有以下兩個好處:
1. 在jabsorb中已經支持IE, Mozilla , Firefox , Safari , Opera, Konqueror 等瀏覽器,因此,使用jabsorb編寫的AJAX程序也就可以跨不同的Web瀏覽器。
2. 使用jabsorb在客戶端和服務端傳遞數據非常方便。在客戶端可以象使用本地對象一樣使用服務端的對象。
下面我們就來看一下如何使用jabsorb來編寫基于AJAX的Web程序。本文使用Tomcat6.x作為Web服務器,讀者可以根據需要使用其他的Web服務器。
一、jabsorb的安裝
安裝jabsorb需要如下幾步:
第1步:加入jar包
jabsorb需要三個jar包:jsonrpc-1.0.jar、jsonrpc-1.0.jar和slf4j-api-1.4.2.jar,這三個文件都可以在jabsorb的壓縮包中找到。將這三個文件放到<Tomcat安裝目錄>"lib目錄中,或是放到<Web根目錄>"WEB-INF"lib目錄中。
第2步:配置web.xml
打開<Web根目錄>\WEB-INF\web.xml,并加入如下的配置代碼:
<servlet>
<servlet-name>JSONRPCServlet</servlet-name>
<servlet-class>org.jabsorb.JSONRPCServlet</servlet-class>
<init-param>
<param-name>gzip_threshold</param-name>
<param-value>0</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>JSONRPCServlet</servlet-name>
<url-pattern>/JSON-RPC</url-pattern>
</servlet-mapping>
這段代碼配置了一個jabsorb引擎,實際上就是一個Servlet(和Struts1.x類似,也是通過Servlet作為入口的)。其中gzip_threshold可以取-1、0和一個正整數。如果值為-1,表示不會對響應的內容進行壓縮,如果為0,表示對響應的所有內容進行壓縮,如果為一個正整數,表示當響應內容超過這個整數時,進行壓縮。
但當瀏覽器不支持gzip壓縮格式,或是經過壓縮后的尺寸要比不壓縮的尺寸還大時(當響應內容比較少時可能發生這種情況),jabsorb就不會對響應內容進行壓縮。因此,最好將這個值設為0,但這樣做所付出的代價是可能會對所有的響應內容進行壓縮。具體要設成什么值,讀者可根據自己的具體情況決定。
第3步 將jsonrpc.js復制到<Web根目錄>\script中,讀者也可以將其放到<Web根目錄>中的其他可訪問的位置。這個文件也可以在jabsorb的壓縮包中找到。
二、編寫一個簡單的jabsorb應用程序
第1步編寫一個用客戶端訪問的Java類。
package invoke;
public class Message implements java.io.Serializable
{
public String getMessage(String s)
{
return "你好 " + s;
}
}
第2步 編寫JSP代碼
<%-- index.jsp --%>
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript" src="script/jsonrpc.js"></script>
<script type="text/javascript">
function onLoad()
{
jsonrpc = new JSONRpcClient("JSON-RPC");
}
window.onload = onLoad;
function invoke()
{
var text = document.getElementById("text");
var result = jsonrpc.msg.getMessage(text.value);
alert(result);
}
</script>
<jsp:useBean id="JSONRPCBridge" scope="session"
class=" org.jabsorb.JSONRPCBridge " />
<jsp:useBean id="message" scope="session"
class="invoke.Message" />
<%
JSONRPCBridge.registerObject("msg", message);
%>
</head>
<body>
<input type="text" id="text"/>
<input type="button" value="獲得信息" onclick="invoke()" />
</body>
</html>
在這個jsp文件中需要做如下四件事才能調用getMessage方法。
1
引用jsonrpc.js文件。
2
在onLoad函數中創建JSONRpcClient對象。JSONRpcClient類的構造方法的參數值就是在web.xml中配置的JSON-RPC。
3
使用<jsp:userBean>創建了org.jabsorb. JSONRPCBridge和invoke.Message對象
4
使用JSONRPCBridge的registerObject方法注冊Message類,其中第一個參數可以是任意的字符串(這個參數是注冊名),第二個參數是Message對象實例。registerObject方法可以對同一個注冊名使用多次,但后一個將覆蓋前一個對象。
在做完上述工作后,就可以使用jsonrpc.msg.getMessage來調用getMessage方法了。
三、在Servlet中使用jabsorb
除了在JSP中使用jabsorb外,也可以在Servlet中使用它。代碼如下:
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
HttpSession session = request.getSession();
JSONRPCBridge bridge = (JSONRPCBridge) session.getAttribute("JSONRPCBridge");
if(bridge == null)
{
bridge = new JSONRPCBridge();
session.setAttribute("JSONRPCBridge", bridge);
}
bridge.registerObject("msg", message);

}
從上面的代碼可以看出,在Servlet中使用jabsorb,實際上就是使用registerObject方法來注冊Message類。然后可以forward到使用jabsorb的JSP頁面,也可以使用PrintWriter在當前Servlet中輸出相應的javascript和html代碼。
四、注冊全局對象
使用registerObject注冊的對象只能在當前頁面訪問。如果想注冊一次,就可以任何運行在當前Web服務器的頁面(JSP、HTML等)中使用這個對象,就需要使用如下的代碼來注冊Message對象:
JSONRPCBridge.getGlobalBridge().registerObject("globalMsg", message);
讀者可以將上面的相應代碼換成這行代碼,然后另建立一個test.jsp,然后使用如下的代碼調用getMessage方法:
<script type="text/javascript" src="script/jsonrpc.js"></script>
<script type="text/javascript">
try
{
jsonrpc = new JSONRpcClient("JSON-RPC");
// 如果將globalMsg換成msg,將拋出[object error]錯誤
var result = jsonrpc.globalMsg.getMessage("bill");
alert(result);
}
catch(e)
{
alert(e);
}
</script>
但經筆者測試,在firefox中訪問test.jsp,竟然可以訪問msg對象,但在IE里就會拋出對象錯誤異常。
五、訪問集合類型
如果反回的數據很多的話,可以使用Java提供的集合類型,如將Message因擴展為如下形式:
package invoke;
public class Message implements java.io.Serializable
{
public String getMessage(String s)
{
return "你好 " + s;
}
public java.util.List getList()
{
java.util.List list = new java.util.LinkedList();
list.add("中國");
list.add(1234);
return list;
}
public java.util.Map getMap()
{
java.util.Map map = new java.util.HashMap();
map.put("bird", "鳥");
map.put("human", "人類");
return map;
}
}
index.jsp中可加入如下的代碼來訪問getList、getMap方法中的數據:
<script type="text/javascript">
jsonrpc = new JSONRpcClient("JSON-RPC");
alert(jsonrpc.globalMsg.getList().list[1]);
alert(jsonrpc.globalMsg.getMap().map['bird']);
</script>
六、異步調用
上面的代碼都是同步調用,也就是在反回結果之前,客戶端程序會被阻塞。為了在網絡環境不暢的環境下Web程序仍然能運行良好,這就需要進行異步調用。也就是說,客戶端在發送請求后立即返回,直接服務端返回信息,才會調用另一個“回調函數”來獲取結果。
回調函數必須有兩個參數,第一個參數表示返回值,第二個參數表示異常信息。如果無異常信息,第二個參數值為null。下面是一個回調函數:
function asyc(result,e)
{
if(e == null)
alert(result);
}
可以使用下面的代碼以異步方式來調用getMessage方法:
jsonrpc.msg.getMessage(asyc, 'bill');
從上面的代碼可以看出,異步調用和同步調用的區別就是異步調用需要將回調函數作為方法的第一個參數傳入被調用的方法。后面跟著被調用方法的參數值。
新浪微博:http://t.sina.com.cn/androidguy 昵稱:李寧_Lining