以下分析纯属个人简洁,不足之处望指教;以下分析在DWR20中,版本不同之处勿怪;
beginBatch():
beginBatch方法在engine.js中出现两次,一次是_execute()代码段开始,一处就是方法定义处;
dwr.engine.beginBatch = function() {
if (dwr.engine._batch) {
dwr.engine._handleError(null, { name:"dwr.engine.batchBegun", message:"Batch already begun" });
return;
}
dwr.engine._batch = dwr.engine._createBatch();
};
方法开始执行,dwr.engine._batch初始为null,因为if(null)不成立;执行dwr.engine.createBatch()方法;
官方解释:生成一个标准的batch对象
dwr.engine._createBatch = function() {
var batch = {
map:{
callCount:0,
page:window.location.pathname + window.location.search,
httpSessionId:dwr.engine._getJSessionId(),
scriptSessionId:dwr.engine._getScriptSessionId()
},
charsProcessed:0, paramCount:0,
parameters:{}, headers:{},
isPoll:false, handlers:{}, preHooks:[], postHooks:[],
rpcType:dwr.engine._rpcType, //dwr.engine._rpcType默认是dwr.engine.XMLHttpRequest,值为1,即通过ajax调用,默认为异步
httpMethod:dwr.engine._httpMethod,
async:dwr.engine._async,
timeout:dwr.engine._timeout,
errorHandler:dwr.engine._errorHandler,
warningHandler:dwr.engine._warningHandler, //dwr.engine._warningHandler默认调用dwr.engine.debug(message)方法,即控制台输出message
textHtmlHandler:dwr.engine._textHtmlHandler //默认为空;
};
if (dwr.engine._preHook) batch.preHooks.push(dwr.engine._preHook); //_preHook以及_post默认都为null
if (dwr.engine._postHook) batch.postHooks.push(dwr.engine._postHook);
var propname, data;
if (dwr.engine._headers) { //_headers以及_parameters默认为null,直接返回batch对象
for (propname in dwr.engine._headers) {
data = dwr.engine._headers[propname];
if (typeof data != "function") batch.headers[propname] = data;
}
}
if (dwr.engine._parameters) {
for (propname in dwr.engine._parameters) {
data = dwr.engine._parameters[propname];
if (typeof data != "function") batch.parameters[propname] = data;
}
}
return batch;
};
生成标准dwr.engine._batch对象如下:
以上属性均为默认,除httpSessionId page scriptSessionId对象;
dwr.engine._getJSessionId()方法如下:
/** @private What is our session id? */
dwr.engine._getJSessionId = function() {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i];
while (cookie.charAt(0) == ' ') cookie = cookie.substring(1, cookie.length);
if (cookie.indexOf(dwr.engine._sessionCookieName + "=") == 0) {
return cookie.substring(dwr.engine._sessionCookieName.length + 1, cookie.length);
}
}
return "";
};
解释下:1.session是服务器端存储技术,浏览器默认通过发送key为JSESSIONID的cookie,所以如果浏览器禁用了SESSION,还可以通过URL重写将JSESSIONID写在地址栏使用SESSION;
2.在tomcat6下可以通过该方法获取到JSESSIONID,但是在tomcat7下document.cookie无法获取到JSESSIONID这条cookie,解决方案 tomcat conf目录下server.xml中对应Context添加useHttpOnly="false"即可,亲测可行
dwr.engine._getScriptSessionId()方法如下:
/** The function that we use to fetch/calculate a session id */
dwr.engine._getScriptSessionId = function() {
if (dwr.engine._scriptSessionId == null) {
dwr.engine._scriptSessionId = dwr.engine._origScriptSessionId + Math.floor(Math.random() * 1000);
}
return dwr.engine._scriptSessionId;
};
/** The original page id sent from the server */
dwr.engine._origScriptSessionId = "009659986C0DAED0AE65D2B30BF1FC1E";
所以dwr.engine._getScriptSessionId()为生成随机的一串ID标识;
page:window.location.pathname + window.location.search,
dwr.engine._batch.map.Page属性为:window.location.pathname为项目路径直到?前面值,window.location.search为?之后参数值;
dwr.engine._debug()方法分析:
--第一个参数为控制台输出信息,第二个参数为是否打印堆栈信息 调用console.trace()方法;
/** @private Used internally when some message needs to get to the programmer */
dwr.engine._debug = function(message, stacktrace) {
var written = false;
try {
if (window.console) {
if (stacktrace && window.console.trace) window.console.trace();
window.console.log(message);
written = true;
}
else if (window.opera && window.opera.postError) {
window.opera.postError(message);
written = true;
}
}
catch (ex) { /* ignore */ }
if (!written) {
var debug = document.getElementById("dwr-debug");
if (debug) {
var contents = message + "<br/>" + debug.innerHTML;
if (contents.length > 2048) contents = contents.substring(0, 2048);
debug.innerHTML = contents;
}
}
};
调用方法可以默认有两种DWREngine._debug('我是debug信息',true)或者dwr.engine._debug('我是debug信息');
效果如下:
dwr.engine._handleError()方法如下:
代码作用:会弹窗提示错误信息,两个参数 batch以及ex. ex为JS对象,指定message属性为弹框提示内容,不指定message属性的话就提示"A server error has occured."
dwr.engine.defaultErrorHandler = function(message, ex) {
dwr.engine._debug("Error: " + ex.name + ", " + ex.message, true);
if (message == null || message == "") alert("A server error has occured.");
// Ignore NS_ERROR_NOT_AVAILABLE if Mozilla is being narky
else if (message.indexOf("0x80040111") != -1) dwr.engine._debug(message);
else alert(message);
};
通常batch传入为null时,调用_errorHandler方法,默认的_errorHandler为dwr.engine._errorHandler = dwr.engine.defaultErrorHandler;
dwr.engine.defaultErrorHandler = function(message, ex) {
dwr.engine._debug("Error: " + ex.name + ", " + ex.message, true);
if (message == null || message == "") alert("A server error has occured.");
// Ignore NS_ERROR_NOT_AVAILABLE if Mozilla is being narky
else if (message.indexOf("0x80040111") != -1) dwr.engine._debug(message);
else alert(message);
};
实例代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="/DWRDemo/dwr/engine.js"></script>
</head>
<body>
<script type="text/javascript">
window.onload=function(){
dwr.engine._handleError(null, { name:"dwr.engine.invalidRpcType", message:"RpcType must be one of dwr.engine.XMLHttpRequest or dwr.engine.IFrame or dwr.engine.ScriptTag" });
//弹窗提示 message
}
</script>
</body>
</html>
运行效果: