小试XML-RPC(浏览器javascript与服务器java通信)

前些天无意中发现了XML-RPC(不过笑我才发现啊hitwall.gif),总想找个机会摆弄摆弄。毕业论文基本上弄完了,所以决定今天把它弄明白。
XML-RPC的最大用处,我首先想到的是浏览器在不刷新页面的情况下与服务器通信,请求数据。下面我就说一下我用XML-RPC是怎么实现的。

第一步:选择XML-RPC实现。
XML-RPC的一个很大优势就是 它是一个标准,并且各种开发环境下都有实现(酷),这是它能够轻松跨平台的原因。
javascript有3个实现。我看了一下最好的应该是jsolait(JavaScript o Lait)的实现了。因为他不仅仅是一个xml-rpc的实现,除此之外还有很多javascript库,详细内容请看这里(http://jsolait.net/)。
java的实现就更多了,我当然毫不犹豫地选择apache的。详细内容看这里(http://ws.apache.org/xmlrpc/

第二步:建立服务。
用java建立xml-rpc有两种方式,一种是单独开个端口,一种是用servlet。我们客户端是用javascript,那么服务端用servlet是再好不过的了。
如何使用apache的xml-rpc,请详细看apache的资料。(大哥你不会连servlet也不会建吧,那你还是不要往下看了)。
代码如下:
这是一个sayHello的服务类:

ExpandedBlockStart.gif ContractedBlock.gif public   class  HelloService  dot.gif {
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif 
public String sayHello(String name)dot.gif{
InBlock.gif  
return "Hello: "+name+" !";
ExpandedSubBlockEnd.gif }

InBlock.gif
ExpandedBlockEnd.gif}

None.gif
None.gif


下面是一个Math服务类:

ExpandedBlockStart.gif ContractedBlock.gif public   class  MathService  dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif 
public double add(Vector v)dot.gif{
InBlock.gif  
double a = Double.parseDouble((String)v.get(0));
InBlock.gif  
double b = Double.parseDouble((String)v.get(1));
InBlock.gif  
return a+b;
ExpandedSubBlockEnd.gif }

InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif 
public double mult(Vector v)dot.gif{
InBlock.gif  
double a = Double.parseDouble((String)v.get(0));
InBlock.gif  
double b = Double.parseDouble((String)v.get(1));
InBlock.gif  
return a*b;
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}


接着是Servlet啦,作为RPC Server用的,这段代码比较经典,很多资料上都有。

ExpandedBlockStart.gif ContractedBlock.gif public   class  RpcServer extends HttpServlet  dot.gif {
InBlock.gif 
protected void doPost(HttpServletRequest request,
ExpandedSubBlockStart.gifContractedSubBlock.gif   HttpServletResponse response) throws ServletException, IOException 
dot.gif{
InBlock.gif  XmlRpcServer xmlrpc 
= new XmlRpcServer();
InBlock.gif  xmlrpc.addHandler(
"HelloService"new HelloService());
InBlock.gif  xmlrpc.addHandler(
"MathService",new MathService());
InBlock.gif  
byte[] result = xmlrpc.execute(request.getInputStream());
InBlock.gif  response.setContentType(
"text/xml");
InBlock.gif  response.setContentLength(result.length);
InBlock.gif  OutputStream 
out = response.getOutputStream();
InBlock.gif  
out.write(result);
InBlock.gif  
out.flush();
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

 

主要是这三句:
XmlRpcServer xmlrpc = new XmlRpcServer();
xmlrpc.addHandler("HelloService", new HelloService());
xmlrpc.addHandler("MathService",new MathService());
一定要记牢Handler的名字,就是第一个参数,因为客户端就靠他来表示要调用的方法呢。

行了现在可以在web.xml中写入配置了:

None.gif   < servlet >
None.gif  
< servlet-name > RpcServer </ servlet-name >
None.gif  
< servlet-class > org.mstar.rpc.RpcServer </ servlet-class >
None.gif 
</ servlet >
None.gif 
< servlet-mapping >
None.gif  
< servlet-name > RpcServer </ servlet-name >
None.gif  
< url-pattern > /RpcServer </ url-pattern >
None.gif 
</ servlet-mapping >


至此,服务端的工作已经完成,启动应用服务器就行了。

下面是javacript的实现,这也是难点(其实不难理解,只是没有中文材料)。
把jsolait的库下来以后解压缩,得到一些js文件,具体我就不说了。

建立一个html文件:

None.gif < html >
None.gif
< head >
None.gif
< title > XML-RPC </ title >
None.gif
< script  type ="text/javascript"  src ="./js/init.js" ></ script >
None.gif
< script  type ="text/javascript"  src ="./js/lib/urllib.js" ></ script >
None.gif
< script  type ="text/javascript"  src ="./js/lib/xml.js" ></ script >
None.gif
< script  type ="text/javascript"  src ="./js/lib/xmlrpc.js" ></ script >
None.gif
< script  type ="text/javascript"  src ="./js/hello.js" ></ script >
None.gif
</ head >
None.gifa:
< input  type ="text"  id ="a"   />< br >
None.gifb:
< input  type ="text"  id ="b"   />< br >
None.gif
< input  type ="button"  id ="do1"  value ="a+b"  onclick ="add()" />
None.gif
< input  type ="button"  id ="do2"  value ="say"  onclick ="hello()" />
None.gif
< input  type ="text"  id ="result"   />
None.gif
</ html >


注意到前面那一堆javascript的引用吗?就这么写吧。可别把hello.js当成solait的东西啦(看名字也知道啦),你是找不到的。这是我们自己写的:
hello.js

None.gif hello  =   function (){
None.gif 
var  xmlrpc = null ;
None.gif 
try {
None.gif     
var  xmlrpc  =  importModule( " xmlrpc " );
None.gif }
catch (e){
None.gif     reportException(e);
None.gif     
throw   " importing of xmlrpc module failed. " ;
None.gif }
None.gif 
var  addr  =   " http://localhost:8080/Rpc/RpcServer " ;
None.gif 
var  methods  =  [ " HelloService.sayHello " ];
None.gif 
var  rslt;
None.gif 
None.gif 
try {
None.gif        
var  service  =   new  xmlrpc.ServiceProxy(addr, methods);
None.gif        rslt 
=  service.HelloService.sayHello( " MTY " );
None.gif    }
catch (e){
None.gif        
var  em;
None.gif        
if (e.toTraceString){
None.gif            em 
=  e.toTraceString();
None.gif        }
else {
None.gif            em 
=  e.message;
None.gif        }
None.gif        rslt 
=   " Error trace: \n\n "   +  em;
None.gif    }
None.gif document.getElementById(
" result " ).value = rslt;
None.gif}
None.gifadd 
=   function (){
None.gif 
var  xmlrpc = null ;
None.gif 
var  a  =  document.getElementById( " a " ).value;
None.gif 
var  b  =  document.getElementById( " b " ).value;
None.gif 
var  params  =   new  Array();
None.gif params[
0 =  a;
None.gif params[
1 =  b;
None.gif 
try {
None.gif     
var  xmlrpc  =  importModule( " xmlrpc " );
None.gif }
catch (e){
None.gif     reportException(e);
None.gif     
throw   " importing of xmlrpc module failed. " ;
None.gif }
None.gif 
var  addr  =   " http://localhost:8080/Rpc/RpcServer " ;
None.gif 
var  methods  =  [ " HelloService.sayHello " , " MathService.add " ];
None.gif 
var  rslt;
None.gif 
None.gif 
try {
None.gif        
var  service  =   new  xmlrpc.ServiceProxy(addr, methods);
None.gif        rslt 
=  service.MathService.add(params);
None.gif    }
catch (e){
None.gif        
var  em;
None.gif        
if (e.toTraceString){
None.gif            em 
=  e.toTraceString();
None.gif        }
else {
None.gif            em 
=  e.message;
None.gif        }
None.gif        rslt 
=   " Error trace: \n\n "   +  em;
None.gif    }
None.gif document.getElementById(
" result " ).value = rslt;
None.gif}
None.gif
None.gif


这个js文件中有两个函数,一个负责从sayhello,一个负责加法运算。
这里需要一些解释的地方:
1、
 var xmlrpc=null;
 try{
     var xmlrpc = importModule("xmlrpc");
 }catch(e){
     reportException(e);
     throw "importing of xmlrpc module failed.";
 }
这里是把xmlrpc模块引进来,你也就这么写吧,我也不知道为什么。
2、
 var addr = "http://localhost:8080/Rpc/RpcServer";
 var methods = ["HelloService.sayHello"];
定义服务地址和要用的方法名。规则大概你也能看懂:Handler名.方法名。这里的Handler名就是你在xmlrpcServer中注册名,就是我上面让你记住的那个。方法名就是那个类自己的方法名。注意,methods是一个数组,所以可以写多个方法,如第二个例子。var methods = ["HelloService.sayHello","MathService.add"];
3、
    try{
        var service = new xmlrpc.ServiceProxy(addr, methods);
        rslt = service.HelloService.sayHello("MTY");
    }catch(e){
        var em;
        if(e.toTraceString){
            em = e.toTraceString();
        }else{
            em = e.message;
        }
        rslt = "Error trace: \n\n" + em;
    }
通过new xmlrpc.ServiceProxy(addr, methods);得到服务代理。
然后调用服务的方法就行了,方法就是代理.Handler名.方法名(参数)。好像参数只能有一个,在第二个例子中我开始有两个参数a,b会发生错误。怎么办?没办法,在javascript用Array传参数,在java用Vector接参数(为什么用Vector,因为xml-rpc规范中的Array,apache使用Vector实现的,为什么javascript不用Vector,因为js没有Vector,且js的的Array是可变长的)。当然这就需要很多java端类型转换工作,js是弱类型的就不用转换了。

xmlrpc.jpg
xmlrpc2.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值