JSON-RPC for JAVA

[-]

  1. 目   录
  2. 概述
    1. 创意背景
    2. 应用前景和展望
    3. 术语
      1. 开源项目地址
      2. 工程svn下载地址
      3. 示例工程下载地址
  3. 环境
    1. 支持的浏览器
    2. 开发环境
    3. 运行环境
  4. 同类产品分析比较
    1. 更加灵活的注册方式
    2. 支持级联调用和复杂对象作为入参
  5. 参数
    1. Java服务方法入口参数类型
    2. Java对象到JavaScript对象的对照表
    3. 注意事项
  6. 功能介绍
    1. 自动捕获异常
    2. JavaScript中释放注册的Java服务对象
    3. 级联调用功能
    4. 按需加载JavaScript库
      1. Base
  7. 使用
    1. Webxml配置
    2. 引入Jar包
    3. AJAX服务Java类的编写
      1. JsonRpcObject基类中的方法列表
      2. 服务类示例
      3. 自己基类的编写
      4. 注意事项
      5. AJAX服务Java类的注册
      6. 自己注册基类的编写
      7. 银海公司专用服务类示例
    4. JSP中的使用
      1. 引入JsonRpcClientjs
      2. 调用
      3. 调用未注册和配置的类方法

[轻量级、零入侵、级联调用JSON-RPC for JAVA AJAX框架]

 

 

JSON-RPC for Java2.5使用说明

 

 

 


 


   

   ...3

概述...5

创意背景...5

应用前景和展望...5

术语...5

链接...6

作者相关链接...6

开源项目地址...6

工程svn下载地址...6

示例工程下载地址...6

环境...7

支持的浏览器...7

开发环境...7

运行环境...8

同类产品分析比较...8

更加灵活的注册方式...8

支持级联调用和复杂对象作为入参...8

参数...8

Java服务方法入口参数类型...8

Java对象到JavaScript对象的对照表...9

功能介绍...10

自动捕获异常...10

JavaScript中释放注册的Java服务对象...10

级联调用功能...11

按需加载JavaScript...11

Base.11

使用...12

Web.xml配置...12

引入Jar...13

AJAX服务Java类的编写...13

JsonRpcObject基类中的方法列表...13

服务类示例...13

自己基类的编写...15

注意事项...15

AJAX服务Java类的注册...16

自己注册基类的编写...16

银海公司专用服务类示例...18

JSP中的使用...19

引入JsonRpcClient.js.19

调用...19

调用未注册和配置的类方法...20

 


 

 

概述

继《JavaScript高级应用与实践》(电子工业出版社.博文视点)之后推出的json-rpc-for-java开源代码,是仅仅100行的javascript代码和不到10java文件实现的超级轻量级的通过 javaScript快速调用java对象并返回任意对象的轻量级框架,并且支持级联调用,也就是说不需要额外的JavaScript编程,就可以通过javascript调用被注册的java对象并返回java对象,如果被返回的对象还有方法,这个在javascript中返回的java对象的变量,还可以继续调用它的方法.....这就是这个轻量级json-rpc-for-java的神奇之处。

创意背景

发现其他的JSON-RPC开源的JavaScript代码太过繁杂,不够简洁,可维护性太差,而其注册复杂、配置繁多,使用不方便,并且不支持复杂对象的传入和级联调用功能。

应用前景和展望

该框架将封装即将发展多个扩展包:

1.        验证包:用于常规的Web开发验证使用,比如身份证、邮件地址、电话号码、邮编、期号等;

2.        JavaScript功能包:包括UI、功能的对象封装,其好处是不在是常规的将JavaScript代码下载到浏览器进行使用,而是按需加载,从而降低网络流量,提高网络的浏览速度。

3.        其他服务包:包装google的在线翻译服务、图表服务等

术语

缩写

全称

描述

JSON

JavaScript  Object Notation

JavaScript对象的一种字面量描述格式,是一种轻量级的数据交换格式——相对于XML,易于人阅读和编写,同时也易于机器解析

RPC

Remote  procedure call

远程过程(函数、方法)调用

AJAX

asynchronous  JavaScript and XML

狭义的解释是:异步的使用XMLJavaScript进行交互和通讯的一种技术;广义的而言,指一切Web上异步的技术

Java

 

一种编程语言

JavaScript

 

一种编程语言

 

开源项目地址

http://code.google.com/p/json-rpc-for-java/

 

工程svn下载地址

http://json-rpc-for-java.googlecode.com/svn/trunk/

不需要用户名和密码。

示例工程下载地址

 

http://json-rpc-for-java.googlecode.com/files/JsonRpcExample2008-08-05.rar

 

测试环境:MyEclipseJRE1.4(1.6)tomcat 5.0(6.0)如果你要测试,可以采用相应的环境,不一定要那么高版本的环境,Import工程后请注意修改工程中JRE为正确的本版路径,如下图所示:

 

环境

支持的浏览器

IE4、IE5、IE6、IE7、IE8、>= FireFox 2.0、>= Opera、>= Safari、google浏览器等等。力求设计与操作系统无关。

开发环境

Tomcat 6.0Eclipse 3.2JDK1.4

运行环境

JRE1.4或以上的J2EE环境。

同类产品分析比较

更加灵活的注册方式

DWR相比,它更加灵活,既能够通过web.xml静态为所有访问者注册JSON-RPC服务对象,还能动态通过代码进行注册,并且所有调用的方法不需要事先声明和注册。

支持级联调用和复杂对象作为入参

区别与其他JSON-RPC框架的是,它支持级联调用,对RPCjava服务方法,还支持传入复杂如MapJavaBean这样的对象。

参数

Java服务方法入口参数类型

JavaScript类型到Java类型的对照如下,如果入口参数为复杂对象,则要求必须是能实例化的类型

JavaScript对象

Java对象

说明

String

java.lang.String

字符串

java.lang.Object

Java复合类型,通常是JavaBean对象,或者是java.util.Map

如果子元素不是简单类型,则遵循其他规则,否则以String处理,并且不支持深度嵌套的对象

number

java.util.Date

java.sql.Timestamp

如果调用参数是日期类型,则自动以数字进行处理:new  Date(Long.parseLong(szTmp01));

java.lang.Boolean

Blooean

对应的值:true、false

String

java.lang.Character

单引号的字符串,例如:‘c’

Number

 

java.lang.Short、

java.lang.Integer、

java.lang.Long、

java.lang.Float、

java.lang.Double、

java.math.BigDecimal

JavaScript中都为数字对象,到参数里后自动转换类型

null

null

空对象

 

 

 

如果转换失败,入口参数将是一个没有数据的入口参数对象,如果转换发生异常,则以null传入。

Java对象到JavaScript对象的对照表

调用异常时返回false

Java对象

JavaScript对象

说明

java.lang.String

String

 

java.lang.Object

String

调用java对象的toString()后转换到JavaScript里

java.util.Date、java.sql.Timestamp

String

格式为yyyy-MM-dd HH:mm:ss.000,如果时分秒都为0,则为:yyyy-MM-dd

java.lang.Boolean

Blooean

对应的值:true、false

java.lang.Character

String

单引号的字符串,例如:‘c’

java.lang.Short、

java.lang.Integer、

java.lang.Long、

java.lang.Float、

java.lang.Double、

java.math.BigDecimal

Number

到JavaScript中都为数字对象,可以直接参与加、减、乘、除运算

java.util.Map

Object

例如:obj[“key1”]、obj[“key3”]、obj.key3,唯独没有以function作为属性的方法,当然,属于Object.prototype的function属性依然有的

java.util.List

Array

例如:a[0]、a[2].getList()

也就是说List里也可以存在复合对象,这些对象依然可以有自己的方法

null

null

空对象

其他Java对象

Object

例如:obj.displayName()、obj.aac001,可以有属性和方法

返回类型

 

实现接口

jcore.jsonrpc.common.face.IResultObject

这样,在JavaScript中不用再调用getErrMsg,直接使用你存放异常消息的变量名就可以获得异常、错误消息。

实例化:

或者在你的异步服务方法中实例化:

jcore.jsonrpc.common.ResultObject

调用ResultObject.setResult将你实际返回的对象set进去,这样,当发生异常消息的时候可以在js中用如下的方式获取

// 错误消息,和结果一次性取出,而不用调用getErrMsg

// 因为当调用getErrMsg的时候就会再次发起异步请求

var szMsg = rpcRstObj['errMsg'],

// 这是返回的对象

oRst = rpcRstObj['result']

;

注意事项

如果你的java服务对象返回的是ObjectBeanMap或者自定义对象,不能有属性_name__id_,这两个属性被本框架内部使用;

 

功能介绍

自动捕获异常

在你编写的java服务类的方法中不需要try{….}catch(Exceptione){},本框架会为你捕获异常错误消息,当你在javascript中没有获取到正确的数据,可以调用异步对象的方法getErrMsg()获取异常消息,该方法封装在jcore.jsonrpc.common.JsonRpcObject中,也就是AJAX服务java基类中。

当返回类型为:

jcore.jsonrpc.common.ResultObject

jcore.jsonrpc.common.face.IResultObject

则可以只用通过返回的对象中获取oRst['errMsg']异常消息。

 

 

JavaScript中释放注册的Java服务对象

你只需要在JavaScript中调用release()就可以释放注册的Java对象资源,详细见示例工程,或者见:

http://code.google.com/p/json-rpc-for-java/wiki/Wiki32

级联调用功能

不明白的地方请结合示例工程进行理解。

1、Java中注册复合对象myjsonrpc

2、JSPJavaScript中获取该对象:var myjsonrpc= JsonRpcClient().myjsonrpc;

3、调用被注册的java对象的方法getMyObj,返回复合的java对象TestDomain:

var oDomain = myjsonrpc. getMyObj();

// 继续调用该返回的java对象的方法

alert(oDomain. toXml())

或者:alert(myjsonrpc.getList()[1].toXml());

如果toXml返回的还是一个复合的Java对象,你可以继续在JavaScript中继续调用,而不需要额外的编程。

按需加载JavaScript

Base

方法名

说明

使用举例

A(a)

转换有length属性的对象为Array。将参数a对象转换为有效的Array对象;a参数必须为有效的拥有length属性的对象

var json =  JsonRpcClient("JRPC");

var o =  json.LoadJsObj("Base");

o.id("myDivId");//  获取对象

// 自动保存滚动条的位置

o.autoSaveScroll("myTextArea");

id(s)

根据id获取对象。如果参数s为String,则以他为id获取对象并返回,否则返回s

addEvent(o,t,f)

给对象绑定事件处理。

o:为HTML对象

t:为事件名,例如click、focus

f:为事件处理函数

getCookie(k)

获取名字为k的cookie值

setCookie(k,v)

将名字为k,值为v的键值对设置到cookie;如果v为无效的值,则删除该项cookie

autoSaveScroll(o)

设置对象o为自动保存滚动条位置——人性化设计

clearScroll(o)

通常,在提交数据后不需要保持对象的滚动条位置,因此需要调用该方法在提交数据前清楚滚动条存储信息

 

使用

Web.xml配置

需要在web.xml中加入下面的配置

   

<servlet>

        <servlet-name>JSONRPCServlet</servlet-name>

        <servlet-class>

            jcore.jsonrpc.servlet.JSONRPCServlet

        </servlet-class>

   

<!—

这里注册的对象将对所有访问者起作用

<init-param>

            <param-name>regAppClassNames</param-name>

            <param-value>

        注册这些对象,让所有的web用户都能使用这些JSON-RPC java对象

        这些对象会复制到每个用户的session对象中,因此他们必须实现接口Serializable

          以分号作为分割符号

                myTest:jcore.jsonrpc.test.Test;

                myTrs:jcore.jsonrpc.test.A

            </param-value>

        </init-param>

-->

 

        <load-on-startup>2</load-on-startup>

    </servlet>

    <servlet-mapping>

        <servlet-name>JSONRPCServlet</servlet-name>

        <url-pattern>/JRPC</url-pattern>

    </servlet-mapping>

 

引入Jar

需要在工程中引入:JSON-RPC.jarcommons-logging.jarcommons-logging-api.jar,其中后面两个jar在示例工程中的JsonRpcExample\webapp\WEB-INF\lib\下。示例工程下载地址:

http://json-rpc-for-java.googlecode.com/files/JsonRpcExample2008-08-05.rar

而,JSON-RPC.jar,你也可以引入源代码重新进行打包。

AJAX服务Java类的编写

JsonRpcObject基类中的方法列表

方法名

说明

getErrMsg

javaScript中调用获取异常、错误消息使用

getRequest

java服务的jcore.jsonrpc.common.JsonRpcObject继承子类中使用,获取到request对象,以便获取session等对象

setErrMsg

同上,在继承的子类中设置错误或异常消息的方法;该方法是框架抓取异常消息填写的方法

setRequest

框架系统使用,注入request的地方

 

服务类示例

必须继承与jcore.jsonrpc.common.JsonRpcObject并实现接口java.io.Serializable

例如示例工程中的AJAX服务Java类:

package test;

import java.io.Serializable;

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import jcore.jsonrpc.common.JsonRpcObject;

 

publicclass TestObjectextendsJsonRpcObject  implementsSerializable{

    privatestaticfinallongserialVersionUID = 1L;

 

    private ListmyList = new ArrayList();

    private Mapmap = new HashMap();

   

    public TestObject()

    {

        myList.add("good");

        myList.add(new TestDomain());

        // map中也可以放入复合对象

        map.put("first","第一条值");

        map.put("p2",new Date());

        map.put("domain",myList.get(1));

    }

   

    /***

     *返回Map对象

     *@return

     */

    public Map getMap()

    {

        returnmap;

    }

   

    /***

     *获取一个普通对象

     *@return

     */

    public Object getStr()

    {

        returnmyList.get(0);

    }

   

    /***

     *获取一个复合对象

     *@return

     */

    public Object getMyObj()

    {

        returnmyList.get(1);

    }

   

    /***

     *获取List对象

     *@return

     */

    public List getList()

    {

        returnmyList;

    }

}

 

自己基类的编写

同样,你可以继承jcore.jsonrpc.common.JsonRpcObject实现一些基类,这样在自己的项目中更加方便实用,例如:

package  com.yinhai.yhsi2.web.common;

 

import com.yinhai.webframework.session.UserSession;

import  jcore.jsonrpc.common.JsonRpcObject;

 

public abstract  class Yhsi2JsonRpcObj extends JsonRpcObject {

 

          private UserSession us = null;

          public Yhsi2JsonRpcObj() {

                   super();

         }

 

         public UserSession getUs() {

                   if(null == us)

                            us =  UserSession.getUserSession(getRequest());

                   return us;

         }

}

 

注意事项

 

RPCJava服务类返回的对象不能有成员变量引用自身对象,服务类对象不能有成员变量为ServiceBPO对象,因为这些对象内部通常有一个成员变量引用了自身,这会导致服务类无法正常转换为正确的JavaScript对等的应用类,会导致堆栈溢出的控制台异常错误信息——我们预计在下一版本中增强这样的自身引用的检测并加以回避。

AJAX服务Java类的注册

// 注意,被注册的类必须是能被实例化的类

 

jcore.jsonrpc.common.JsonRpcRegister.registerObject(us,"myjsonrpc", test.TestObject.class);

 

使用test.TestObject.class的方式是保证多次注册不至于test.TestObject被多次注册而执行多次实例化,从而提高性能,并允许多次注册——实际上内部只注册了一次。

自己注册基类的编写

当然,你也可以继承jcore.jsonrpc.common.JsonRpcRegister以便使得在应用菜单切换的时候释放资源,例如:

package com.yinhai.yhsi2.web.common;

import javax.servlet.http.HttpServletRequest;

 

import jcore.jsonrpc.common.Content;

import jcore.jsonrpc.common.JSONRPCBridge;

 

import com.yinhai.webframework.session.UserSession;

import jcore.jsonrpc.common.JsonRpcRegister;

 

/***

 * 注册JsonRpc对象

 * @author just

 *

 */

public class JsonRpcRegister extends  jcore.jsonrpc.common.JsonRpcRegister{

 

         /***

          * 通过request来注册对象

          * @param request

          * @param szKeyName

          * @param o

          */

         public  static void registerObject(HttpServletRequest request, String szKeyName,  Object o)

         {

                   registerObject(UserSession.getUserSession(request),  szKeyName, o);

         }

 

         /***

          * 通过request来注册对象

          * @param request

          * @param szKeyName

          * @param o

          */

         public  static void registerObject(UserSession us, String szKeyName, Object o)

         {

                   if(null  != us)

                {

                          JSONRPCBridge brg =  (JSONRPCBridge)us.getCurrentBusiness().getSessionResource(Content.RegSessionJSONRPCName);

                      // 如果是第一次就注册对象

                             if(null == brg)

                                      us.getCurrentBusiness().putSessionResource(Content.RegSessionJSONRPCName,  brg = new JSONRPCBridge().setSession(us.getHttpSession()));

                             brg.registerObject(szKeyName, o);

                }

         }

 

 

 

         /***

          * 通过request来注册对象

          * @param request

          * @param szKeyName

          * @param o

          */

         public  static void registerObject(HttpServletRequest request, String szKeyName,  Class o)

         {

                   registerObject(UserSession.getUserSession(request),  szKeyName, o);

         }

 

         /***

          * 通过request来注册对象

          * @param request

          * @param szKeyName

          * @param o

          */

         public  static void registerObject(UserSession us, String szKeyName, Class o)

         {

                   if(null  != us)

                {

                          JSONRPCBridge brg =  (JSONRPCBridge)us.getCurrentBusiness().getSessionResource(Content.RegSessionJSONRPCName);

                      // 如果是第一次就注册对象

                             if(null == brg)

                                      us.getCurrentBusiness().putSessionResource(Content.RegSessionJSONRPCName,  brg = new JSONRPCBridge().setSession(us.getHttpSession()));

                             try {

                                     brg.registerObject(szKeyName,  o.newInstance());

                            }  catch (InstantiationException e) {

                            }  catch (IllegalAccessException e) {

                            }

                }

         }

}

银海公司专用服务类示例

 

package com.yinhai.yhcip.common;

 

import java.util.Map;

 

import jcore.jsonrpc.common.JsonRpcObject;

 

import com.yinhai.sysframework.persistence.IDao;

import com.yinhai.sysframework.service.ServiceLocator;

 

/**

 * Rpc调用

 * @author just

 *

 */

public class Rpcyhcip extends JsonRpcObject{

 

         /**

          * 远程异步调用过程

          * @param szDaoId  dao名称id

          * @param szSqlId  sql语句id

          * @param map       入口参数

          * @return

          */

         public  boolean delete(String szDaoId, String szSqlId, Map map)

         {

                   try

                   {

                      // 如果需要UserSession对象:UserSession us =  UserSession.getUserSession(this.getRequest());

                      // getRequest方法是父类中实现

                            IDao  dao =(IDao) ServiceLocator.getInstance().getService(szDaoId);

                            return  0 < dao.delete(szSqlId, map);

                   }catch(Exception  e)

                   {

                            e.printStackTrace();

                            setErrMsg(e.getMessage());

                   }

                   return  false;

         }

}

 

 

 

JSP中的使用

引入JsonRpcClient.js

<script charset="UTF-8"type="text/JavaScript" src="JsonRpcClient.js"></script>

最新的文件可以从http://code.google.com/p/json-rpc-for-java/

下载

调用

<script charset="UTF-8"  type="text/JavaScript"><!--//--><![CDATA[//><!--

 

// myjsonrpc就是通过JsonRpcRegister.registerObject注册的名字

// 这时候这里的rpc就拥有了通过JsonRpcRegister.registerObject注册的

// 异步对象的相应方法了

var rpc = JsonRpcClient().myjsonrpc;

// 传入个人编号获取人的基本信息并填充到界面上

if("dto(aac001)" === o.name && 0  === "aab001".getValue().length)

  {

      if(0 <  o.value.length)

      {

      // 获取到的myjsonrpc同样有aac001,aab001等等属性,

// 你可以直接使用,同样有getAac001()等方法,

// 可以直接使用,而不需要额外的编码

                     var myjsonrpc =  rpc.getEmployeeBaseInfo(o.value), errMsg = rpc.getErrMsg();

                     if(0 < errMsg.length)

                        return o.focus(), alert(errMsg), false;

                     for(var k in myjsonrpc)

                       if(6 === k.length && myjsonrpc[k])

                        k.getObj() && k.setValue(myjsonrpc[k]);

                      fnSetAtbt("dto(aac001)".getObj(),1),

                      fnSetAtbt("dto(aab001)".getObj(),4),

                     "aab001".focus();

                     // 关闭错误消息提示

                     ;

           }

  }

// 2008-08-02 增加自动拦截异常消息功能,因此在你写的代码中不需要编写try catch

// 如果有异常消息,可以在js中调用rpc.getErrMsg()获得

// 如果需要释放被注册名为myjsonrpc的对象JsonRpcObj,可以在js中调用rpc.release();

// 2008-08-13 增加对FireFox 3.01的支持,增加传入JavaBeanMap参数的支持

//--><!]]></script>

如果本调用的方法getEmployeeBaseInfo的第一个参数是function,则把它作为异步的回调函数。

调用未注册和配置的类方法

1、             首先,被调用的类需要继承jcore.jsonrpc.common.JsonRpcObject或实现接口jcore.jsonrpc.common.face.IjsonRpcObject,并有默认的构造函数;

例如:

package test.rpc;

import jcore.jsonrpc.common.JsonRpcObject;

public class MyTestRpc extends JsonRpcObject{

              /**

               * 调用:rpc.getRpcObj('test.rpc.MyTestRpc').getTestMsg()

               * @return

               */

              publicString getTestMsg()

              {

                            return"噢,成功了!";

              }

}

2、             JSPJavaScript中调用的方式,例如:alert(rpc.getRpcObj('test.rpc.MyTestRpc').getTestMsg());

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值