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
代码
<!--[if !supportLineBreakNewLine]--><!--[endif]-->
<%
--
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');
从上面的代码可以看出,异步调用和同步调用的区别就是异步调用需要将回调函数作为方法的第一个参数传入被调用的方法。后面跟着被调用方法的参数值。