您的位置:首页 > 编程语言 > Java开发

JSON-RPC for JAVA

2014-10-13 19:50 183 查看
[-]

目 录
概述

创意背景
应用前景和展望
术语

开源项目地址
工程svn下载地址
示例工程下载地址

环境

支持的浏览器
开发环境
运行环境

同类产品分析比较

更加灵活的注册方式
支持级联调用和复杂对象作为入参

参数

Java服务方法入口参数类型
Java对象到JavaScript对象的对照表
注意事项

功能介绍

自动捕获异常
JavaScript中释放注册的Java服务对象
级联调用功能
按需加载JavaScript库

Base

使用

Webxml配置
引入Jar包
AJAX服务Java类的编写

JsonRpcObject基类中的方法列表
服务类示例
自己基类的编写
注意事项
AJAX服务Java类的注册
自己注册基类的编写
银海公司专用服务类示例

JSP中的使用

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

[轻量级、零入侵、级联调用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代码和不到10个java文件实现的超级轻量级的通过 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
狭义的解释是:异步的使用XML和JavaScript进行交互和通讯的一种技术;广义的而言,指一切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

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

环境

支持的浏览器

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

开发环境

Tomcat 6.0、Eclipse 3.2、JDK1.4。

运行环境

JRE1.4或以上的J2EE环境。

同类产品分析比较

更加灵活的注册方式

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

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

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

参数

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服务对象返回的是Object、Bean、Map或者自定义对象,不能有属性_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.jar、commons-logging.jar、commons-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;

}

}

注意事项

RPC的Java服务类返回的对象不能有成员变量引用自身对象,服务类对象不能有成员变量为Service或BPO对象,因为这些对象内部通常有一个成员变量引用了自身,这会导致服务类无法正常转换为正确的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的支持,增加传入JavaBean、Map参数的支持
//--><!]]></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、 JSP的JavaScript中调用的方式,例如:alert(rpc.getRpcObj('test.rpc.MyTestRpc').getTestMsg());
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: