DWR工作流程簡單來說,
例子中jsp中引入/DWRDemo/dwr/interface/dwrDate.js文件中,方法都是調用 _execute方法,框架封裝了_sendData發送ajax請求,後臺返回JS代碼,前端解析,在調用_remoteHandleCallback方法,執行我們寫的回調方法;
dwrDate.getYear = function(callback) {
dwr.engine._execute(dwrDate._path, 'dwrDate', 'getYear', callback);
}
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- 這三個js導入項必不可少 -->
<!-- 每一個對象都會有以一個對象爲名稱的那個js庫 -->
<!-- Dwr 引擎庫 -->
<script type='text/javascript' src='/DWRDemo/dwr/engine.js'></script>
<!-- Dwr 工具庫 -->
<script type='text/javascript' src='/DWRDemo/dwr/util.js'></script>
<script type="text/javascript" src="/DWRDemo/dwr/interface/dwrDate.js"></script>
<script>
window.onload = function(){
dwrDate.getYear(function(data){
document.getElementById("showTime").innerHTML += 1900 + data + " 年 ";
});
dwrDate.getMonth(function(data){
document.getElementById("showTime").innerHTML += 1 + data + " 月 ";
});
};
</script>
</head>
<body>
<div id="showTime">當前時間:</div>
</body>
</html>
記錄下我今天分析的代碼:
1.singleShot我理解爲一個控制批量發送請求的標誌位,true表示不批量發送; |
2.arguments參數爲方法傳入的參數 |
3.所有_execute()方法入參由dwr自動生成,最後一個參數默認爲回調的方法,存儲在callData的callback屬性中,也會保存在handlers[0]的callback屬性裏,後面回調就是調的這個callback |
4.傳遞的參數中包含這樣的參數 c0-scriptName=dwrDate 不使用批量發送的話每次參數都以c0-開頭,因爲每次發送都會new一個新的batch對象,callCount都會從0開始重新增加 |
dwr.engine._execute = function(path, scriptName, methodName, vararg_params) {
var singleShot = false;
if (dwr.engine._batch == null) {
dwr.engine.beginBatch();
singleShot = true;
}
var batch = dwr.engine._batch;
// To make them easy to manipulate we copy the arguments into an args array
var args = [];
for (var i = 0; i < arguments.length - 3; i++) {
args[i] = arguments[i + 3];
}
// All the paths MUST be to the same servlet
if (batch.path == null) {
batch.path = path;
}
else {
if (batch.path != path) {
dwr.engine._handleError(batch, { name:"dwr.engine.multipleServlets", message:"Can't batch requests to multiple DWR Servlets." });
return;
}
}
// From the other params, work out which is the function (or object with
// call meta-data) and which is the call parameters
var callData;
var lastArg = args[args.length - 1];
if (typeof lastArg == "function" || lastArg == null) callData = { callback:args.pop() };
else callData = args.pop();
// Merge from the callData into the batch
dwr.engine._mergeBatch(batch, callData);
batch.handlers[batch.map.callCount] = {
exceptionHandler:callData.exceptionHandler,
callback:callData.callback
};
// Copy to the map the things that need serializing
var prefix = "c" + batch.map.callCount + "-";
batch.map[prefix + "scriptName"] = scriptName;
batch.map[prefix + "methodName"] = methodName;
batch.map[prefix + "id"] = batch.map.callCount;
for (i = 0; i < args.length; i++) {
dwr.engine._serializeAll(batch, [], args[i], prefix + "param" + i);
}
// Now we have finished remembering the call, we incr the call count
batch.map.callCount++;
if (singleShot) dwr.engine.endBatch();
};
createBatch之後singleShot已經變爲true,進入endBatch方法:
endBatch()方法
首先進行了一些校驗工作,dwr.engine._batch不能爲空、batch.map.callCount不能爲零,如果傳入了參數options,options是個對象,支持參數有:rpcType、 httpMethod、async、timeout、errorHandler,、warningHandler、textHtmlHandler,請求消息頭、方法參數等,這樣可以實現局部的個性化,其他方法調用不會引起誤會。_ordered屬性是用來控制是否嚴格按照順序來發送請求得到響應;通過_sendData(batch)發送ajax請求。 |
dwr.engine.endBatch = function(options) {
var batch = dwr.engine._batch;
if (batch == null) {
dwr.engine._handleError(null, { name:"dwr.engine.batchNotBegun", message:"No batch in progress" });
return;
}
dwr.engine._batch = null;
if (batch.map.callCount == 0) return;
// The hooks need to be merged carefully to preserve ordering
if (options) dwr.engine._mergeBatch(batch, options);
// In ordered mode, we don't send unless the list of sent items is empty
if (dwr.engine._ordered && dwr.engine._batchesLength != 0) {
dwr.engine._batchQueue[dwr.engine._batchQueue.length] = batch;
}
else {
dwr.engine._sendData(batch);
}
};
sendData方法太佔篇幅就不貼代碼了;
_sendData方法主要就是ajax發送請求,置於推送模式,暫時沒能力分析,ajax異步請求狀態改變事件爲dwr.engine._stateChange(); 接收到響應類似這樣;通過 if (toEval != null) toEval = toEval.replace(dwr.engine._scriptTagProtection, ""); eval函數調用了eval()方法來解析響應的JS字符串,並執行該方法dwr.engine._remoteHandleCallback,裏面就會執行我們寫入的回調函數了 |
throw 'allowScriptTagRemoting is false.';
//#DWR-INSERT
//#DWR-REPLY
dwr.engine._remoteHandleCallback('0','0',118);