近研究了一下dwr的自动测试方案。在这里抛砖一篇博文。
dwr的协议,还是基于HTTP的。客户端一般会使用POST方法来提交内容给服务器端,服务器端从POST内容里面获知客户端想调用服务端的哪个方法,哪些参数。服务端执行这个方法后,把结果响应给客户端。
以下是一段例子:
callCount=1 scriptSessionId=${scriptSessionId}187 c0-scriptName=AlbumBean c0-methodName=deleteAlbum c0-id=0 c0-param0=number:250497656 batchId=481523
这里可以很清楚的看到,POST的内容里面指定了要访问的是AlbumBean中的deleteAlbum方法,参数是number类型的250497656。其他什么batchId,scriptSessionId,c0-id, callCount等,大多数情况下都是固定的那几个值。
那我如果要写代码自己来提交这个HTTP请求,必须把调用的Bean、方法名,还有参数,以及参数类型都按照这个格式进行包装。
如果再进一步,参数类型都是可以通过js的typeof来自动获取。
然后我的思路是:用java写引擎,负责http传输。用js来接受调用,自动获取参数格式,然后把Bean、方法名,还有参数,以及参数类型发给java引擎,把这些内容组织好post出去。
我们再来看看服务端响应的内容:
//#DWR-INSERT //#DWR-REPLY var s0={};s0.cDocId=-1;s0.coverStorageType=0;s0.createTime=1329811796415; s0.creatorUserId=9552463; s0.curl="http://d1.bst2.126.net/style/img/m/album/none160.gif";s0.description="测试一下"; s0.id=250514017;s0.name="测试一下"; s0.photoCount=0; s0.privacy=0; s0.resourceId=9552463;s0.status=0; s0.type=0; s0.undeletable=false;s0.updateTime=1329811796415; dwr.engine._remoteHandleCallback('997381','0',{albumId:250514017,album:s0,code:100});
这段内容可以分三段看:
第一段,是两行申明,一般都固定
第二段,是第三行,是js格式的一段语句,这段语句用js的语法定义了一个js对象
第三段,后一行,调用了dwr的引擎中的某个方法,参数是json格式的
由于这段内容比较复杂,js格式内容也有,json格式的内容也有,如果想自己写程序获取完整内容,得用些特殊的手段。
我的思路是:这整段返回内容,进行一些简单处理后,直接转化成js的代码,然后用eval来执行这段代码,返回一个js的对象。然后这个js对象转成HashMap,java程序里可以直接调用了。
整合了以上想法后,我弄了两段程序,一段发信息,一段收信息。
代码不全贴了,只放一些体现思想的代码。
发送post请求:
function getResult(script, method, paras){ var typelist = [] for(var i = 0; i < paras.length; i++){ typelist.push(typeof(paras[i])) } var result = "" + engine.getResult(script, method, paras, typelist) return result } .............. public String getResult(String ScriptName, String MethodName, Object[] args, String[] argsTypes) throws Exception{ String posturl = http://xxxxxxxxxxxxxxxx/dwr/call/plaincall/ + ScriptName + MethodName +".dwr"; StringBuffer paramBuffer = new StringBuffer(); paramBuffer.append("callCount=1 scriptSessionId=${scriptSessionId}187 "); paramBuffer.append("c0-scriptName=").append(ScriptName).append(" c0-methodName=").append(MethodName); paramBuffer.append(" c0-id=0");
for(int i=0;i<args.length;i++){ paramBuffer.append(" c0-param").append(i).append("=").append(argsTypes[i]).append(":").append(args[i]); } paramBuffer.append(" batchId=889209 "); return post(posturl, paramBuffer.toString()); }
接收响应内容:注意这里返回的js对象,到java里面,是sun.org.mozilla.javascript.internal.NativeObject对象,其他简单js类型都有相对应的java对象
public static HashMap<String, Object> getResult(String dwrString) throws Exception{ ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("js"); HashMap<String, Object> retMap = new HashMap<String, Object>(); engine.put("inputString", dwrString); engine.put("map", retMap); String jsScriptString = "" + "var re = new RegExp("dwr.engine._remoteHandleCallback\\('\\d+','\\d+',(.*?)\\);", "m") " + "var value = inputString.replace(re, "var __result__ = $1") " + "eval(value) " + "for(var k in __result__) { map.put(k, __result__[k])}"; engine.eval(jsScriptString); return retMap;
}
public static void justtest(String testString) throws Exception{ HashMap<String, Object> map = getResult(testString);
Double albumId = (Double) map.get("albumId"); System.out.println("albumId : " + albumId.intValue()); NativeObject album = (NativeObject) (map.get("album")); System.out.println("album.createTime : " + album.get("createTime", null)); System.out.println("album.curl : " + album.get("curl", null));
}