基于Ajax和Java反射机制的RPC实现:轻量高效的解决前后端交互

/*首先是一个封装的Ajax请求,如下所示

* Ajax类是最底层的Ajax实现。
* 例子:
* var ajax = new Ajax("POST","TestService","some data text", false, function(data){console.log(data);});
* ajax.call();
* 在上面的例子中,第一个参数是请求所使用的方式有"POST"和"GET"两种
* 第二个参数是响应请求的url,通常是一个servlet或php,也可以是asp
* 第三个参数比较特别,它可以是一段任意的字符串数据,该部分数据与一般http请求的url中的“参数”不一样,
* 它在http的body部分而不是头部分,因此,当要传输相对较大的数据到服务器的时候可以规避头溢出异常。
* 第四个参数描述了是异步还是同步,false代表同步,true代表一步
* 第五个参数是请求成功的回调函数


*/


function Ajax(method,url,data,syn,callback){
this.url = url;
this.data = data;
this.syn = syn;
this.callback = callback;
this.method = method;
return this;
}

Ajax.prototype = {

call:function(){
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
me = this;
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
me.callback(xmlhttp.responseText);
} else{
// me.error(xmlhttp.responseText);
}
}
xmlhttp.open(this.method,this.url,this.syn);
xmlhttp.send(this.data);
},
callback:function(data){},
error:function(data){}
}

/*    实现一JS对象,利用如上包装的Ajax类请求后台服务,通过返回值将后台服务接口封装在一个JS对象中:DMC,远程方法直接调用。

1. DMC能智能的创建远程对象,能够是JS程序员像调用Java方法一样执行后台服务
* 例子: 
* 假设我们有这样一个Java类:
* //Java类
* package Test;
* public class Hello{
* public String sayHello(String name){
* return "hello "+ name;
* }
* }
* //--------end----------
* 那么我们可以像这样使用DMC JS框架:
* var helloObject = DMC.create("Test.Hello"); //创建一个Test.Hello对象
* var rst = helloObject.sayHello("sh");//直接调用远程的sayHello方法
* console.log(rst); //终端上会打印出:"hello sh"
* //-----------------------
* 实现DMC框架有意思的地方就在于它会自动的根据后台所提供的Java类创建JS对象。

* 2. DMC通过http的数据部分传值而非头部分,因此不会收到请求头大小溢出的异常。
* 3. 对于前端程序员开发时,DMC还可以方便的被继续封装。尽管使用DMC仅需要2句代码

*/

function DMC(){}

/**
* 用于动态创建的DMCObject,它会根据传入的类模版动态生成JS对象。
*/
function DMCObject(classObject,className){
this.classObject = classObject;
this.className = className;
var tmpObject = {};

tmpObject['call'] =function(className,method,methodName,methodData){
method['values']= Base64.encode(JSON.stringify(methodData));
method['name']=methodName;
var tmpData = JSON.stringify(method);

var returnData = {};
var nc = new Ajax("POST", "/DMC/DMCService?name="+className+"&methodName="+methodName,tmpData,false,function(data){
if(data==null){

}else{
returnData=data;
}
});
nc.call();
return returnData;
};

tmpObject['classObject'] = this.classObject;
for(var m in classObject){


if(typeof classObject[m] =="function") continue;
var pts = classObject[m].parameterType;
var ps = [];
for(var i=0;i<pts.length;i++){
ps[i] = 'x'+i;
}
var f = new Function(ps,"var args = Array.prototype.slice.call(arguments);return this.call('"+className+"',this.classObject['"+m+"'],'"+m+"',args);");
tmpObject[m+""]=f;
}
return tmpObject;
}


var classCache ={}
DMC.prototype = {
load:function(className){
var nc = new Ajax("POST", "/DMC/ClassService?name="+className,"",false,this.fx);
nc.call();
},
fx:function(data){
data = JSON.parse(data);
classCache[data.className+""]=data.methods;
},
create:function(className){
if(className in classCache){

}else{
this.load(className);
}
if(className in classCache){
return new DMCObject(classCache[className+""],className);
}else{
console.log("class "+className+" not found");
return {};
}
}
};

var DMC = new DMC();


后台实现:java

public String doDMCClassService(String className) {
try {
Class cl = LibLoader.getInstance().classForName(className);
if (cl == null) {
return null;
}
JSONObject obj = new JSONObject();
obj.put("className", cl.getName());
JSONObject methods = new JSONObject();
for (Method m : cl.getMethods()) {
JSONObject mo = new JSONObject();
mo.put("returnType", m.getReturnType().getName());
JSONArray ja = new JSONArray();
for (Class pc : m.getParameterTypes()) {
ja.add(pc.getName());
}
mo.put("parameterType", ja);
methods.put(m.getName(), mo);
}
obj.put("methods", methods);

return obj.toString();
} catch (Exception ex) {
ex.printStackTrace();
}

return null;
}

上述方法存在一个Servlet中,通过Servlet服务前端调用此方法动态生成JS对象。

在此Servlet中通过Java反射机制,借助下面的方法前端动态执行Java后台服务。

public Object doDMCService(String name, String methodName, String content, HttpSession session) {
if (content == null) {
System.out.println("null");
return "dodmc";
}
JSONObject obj = null;
try {
obj = JSONObject.fromObject(content);
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
}
String v = new String(Base64.decodeBase64(obj.getString("values")));
try {
Class cl = LibLoader.getInstance().classForName(name);
if (cl == null) {
return name + "not found";
}
Class iHttpSessionAware = LibLoader.getInstance().classForName(IHttpSessionAware.class.getName());
Class iSessionable = LibLoader.getInstance().classForName(ISessionable.class.getName());
JSONArray array = obj.getJSONArray("parameterType");
JSONArray objs;
try {
objs = JSONArray.fromObject(v);
} catch (Exception ex) {
objs = new JSONArray();
System.out.println("0"+ex.getMessage());
return ex.getMessage();
}

Class[] pcs = new Class[array.size()];
Object[] argsvalue = new Object[objs.size()];
int i;
for (i = 0; i < array.size(); ++i) {
pcs[i] = Class.forName(array.getString(i));
}
for (i = 0; i < objs.size(); ++i) {
argsvalue[i] = objs.get(i);
}
Method m = null;
try {
Object to = cl.newInstance();
boolean flag = false;
boolean flag_session = false;

for (Class cls : cl.getInterfaces()) {
if ("SomeInterface".equals(cls.getName())) {
flag = true;
}

}

if (flag) {
     //dosomething
}

}
m = to.getClass().getDeclaredMethod(methodName, pcs);
m.setAccessible(true);
Object rt = m.invoke(to, argsvalue);
if (rt == null) {
return "{}";
}
return rt;
} catch (Exception er) {
er.printStackTrace();
System.out.println( er.getMessage() + m.getName() + "methodname:" + methodName + "args:" + pcs.length + ":" + pcs.toString() + " class:" + cl.getName() + " content:" + content);
} finally {
}
} catch (SecurityException ex) {
Logger.getLogger(DMCService.class.getName()).log(Level.SEVERE, null, ex);
System.out.println( ex.getMessage());
} catch (ClassNotFoundException ex) {
Logger.getLogger(DMCService.class.getName()).log(Level.SEVERE, null, ex);
System.out.println( ex.getMessage());
}
return null;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值