看一下sessionCookieName:
/** The session cookie name */
dwr.engine._sessionCookieName = "${sessionCookieName}"; // JSESSION
ID
The session cookie name它也是服务器端返回给客户端的,所以说服务器端采用什么方式获得了这个sessionCookieName的形式之后,我们的dwr.engine._getJSessionId才能根据它的内容它的形式来返回我们想要的cookie,这个实现方式就是dwr所依赖的实现方式。如果dwr实现了这个cookieName是别的名字,那我们也需要dwr给返回别的名字。dwr.engine._sessionCookieName 这个名字是因框架而定。所以它会采用这样一种写法。
我们看看打印
function show(){
alert("sessionCookieName:" + dwr.engine._sessionCookieName);
}
打印出sessionCookieName:JSESSIONID
那么我们现在取得的JSESSIONID就是JSESSIONID=我们所要的字符串,我们验证一下,用下面的代码:
var cookies = document.cookie.split(';');
alert(cookies );
打印出JSESSIONID=FCB69D86F4E1AC9CF3900A6816。它和origScriptSessionId是不一样的。我们来看看httpSessionId(JSESSIONID),它应该是对一个客户的所有请求来讲的。会话,对多个请求只要是同一个客户都可以,因此对于同一个客户它的httpSessionId是不会变的。我们来看对同一个客户第一次请求JSESSIONID=FCB69D86F4E1AC9CF3900A6816,刷新后第二次请求JSESSIONID=FCB69D86F4E1AC9CF3900A6816,它们俩次显示的JSESSIONID是相同的。因为它们都是相当于同一会话来讲的。这个内容也就是存储在客户端,客户端发送数据的时候也要把它们发送出去,发送出去到服务器端后,服务器端判断这个SESSIONID存不存在。如果存在的话,就会根据它去取出我们所要的session,然后把当前客户这些状态取出来显示出来。
我们看一下原始的脚本ScriptSessionId,我们知道它的产生是服务器每一次进行加载页面,页面中包含了engine.js这个资源的时候,我们会把原始的ScriptSessionId赋值,所以我们每一次的请求都会产生一个不同的ScriptSessionId。所以脚本的原始的ScriptSessionId,针对每一次的不同请求,它都会产生不同的原始的ScriptSessionId。
(四)execute方法
下面我们看一下脚本文件的生成:
Demo.js:
//Provide a default path to dwr.engine
if(dwr == null) var dwr = {};
if(dwr.engine == null) dwr.engine = {};
if(DWREngine == null) var DWREngine = dwr.engine;
if(Demo == null) var Demo = {};
Demo._path = '/Demo1/dwr';
Demo.sayHello = function(p0,callback){
dwr.engine._execute(Demo._path,'Demo','sayHello',p0,callback);
}
这是服务器端为我们产生的脚本文件,正因为有了这个脚本文件,客户端才可以通过Demo.sayHello来访问到服务器组件。到底是怎么访问的?大家知道,dwr是基于ajax产生的,所以它必然会用到ajax的xmlHttpRequest对象,被dwr封装了,包括servlet在ajax中也需要我们来写,但是在dwr中也封装来了,只要在web.xml配置org.directwebremoting.servlet.DwrServlet就可以完成我们的处理了。这也是dwr优于ajax的一点,框架的集成度是比较高的。
看一下Demo.sayHello,它是通过dwr.xml这个部署配置文件来动态产生的, dwr.engine._execute(Demo._path,'Demo','sayHello',p0,callback);这些东西是服务器发我们的,这是dwr的一个内部实现机制。看一下调用Demo.sayHello方法的时候,具体的操作是什么?它首先去调用函数function(p0,callback),说白了,客户端直接调用web服务器的组件呢,实际说到最终的实质也就是服务器端为我们产生一个js脚本文件,产生的这个文件是根据我们的dwr.xml部署描述文件动态生成的,生成之后呢,我们客户端就调用生成的这个文件当中的信息,然后通过这个信息再去调用engine.js文件当中的execute方法,然后把必要的参数传递进去之后,在dwr.engine._execute(Demo._path,'Demo','sayHello',p0,callback);里面完成对象的创建,包括最后的发送,最后的相应等等。所以这个引擎的脚本文件是很重要的。下面分析一下引擎脚本文件中的
dwr.engine._execute方法:
dwr.engine._execute = function(path, scriptName, methodName, vararg_params)
引擎文件的执行方法,需要4个参数,注意一点,看源码的时候, javascript定义一个函数的时候,后面的参数并不是我们在dwr.engine._execute(Demo._path,'Demo','sayHello',p0,callback);里面指定的,因为这是5个参数,但前面引擎文件的执行方法定义时却只有4个参数。这个和强类型语言有所区别,强类型语言对于函数重载方面,它参数不同,它会去调用不同的方法。但是这里如果仅仅有一个函数的话,这个函数的参数不同,它也会去调用。所以不能从参数的数量上来确定调用哪一个函数。vararg_params相当于是一个数组,相当于有很多的参数在里面,这一点一定要注意。所以客户端在调用了Demo.sayHello方法之后,会执行引擎脚本的execute方法,然后会传递几个参数Demo._path,'Demo','sayHello',p0,callback。Demo._path是在服务器端动态的生成的,它也就是指定我们请求的路径是什么。请求都是通过servlet来处理的,请求路径应该就是servlet所需要的路径。Demo指的是dwr.xml文件当中,为我们指定的javascript的属性所指定的在客户端调用的对象的方法的对象的名称,sayHello就是指定我所调用的是哪一个方法,p0就是指定调用的参数是什么(就是本例的name),callback就是回调方法。这就是我们在客户端在书写格式上要采用Demo.sayHello(text,callBack),前面text指的是参数,后面指定的是回调函数callBack。这也是和实现机制有关的,否则我们这么写为什么会去调用它,我们不得而知,但是当你看到了这个生成的引擎文件的时候,我就知道,实际我调用sayHello方法之后,传递的两个参数function(p0,callback),p0是我们传递的参数,callback是回调方法,然后吧这些信息是通过引擎文件的execute方法去执行的。但是传递这个方法的时候,会传递另外一些附加的信息。而且回调函数传过去,传过去之后在引擎中,会对数据进行分析,分析之后回传的时候会去调用callback,然后就会调用我们在index.jsp里面写的callBack(data)方法显示出数据。这就是整体流程。
下面分析引擎文件的执行方法,看源码:
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();
};
path是请求的路径,scriptName是客户端所用的java对象的名称methodName是调用的方法名 vararg_params是方法的参数,这里面的参数是包括了客户端发送给服务器端需要的java方法的参数名称,还有一个就是回调函数。
首先看看dwr.engine.beginBatch();开始一个批处理,目的是因为dwr框架在开发的时候遵循的一种方式就是说,如果多次调用java的web组件的话,我需要放在一个批处理当中来处理,这样会提高效率,避免了客户端和服务器端频繁的发生交互。所以需要一个批处理。但是默认情况下,都会采用批处理,它会生成一个Batch的批处理对象。看一下dwr.engine.beginBatch源码:
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();
};
它也是一个函数,目的就是为了生成一个Batch批处理的对象。生成这个Bactch对象的目的是什么?也就是完成我所需要的操作,操作中的数据都是放在Bactch对象里的,然后通过Bactch来操作,beginBatch需要做的是什么呢?就是如果这个Bactch对象存在的话,就会抛出错误已经存在了,不需要创建,然后直接返回。dwr.engine._batch =
dwr.engine._createBatch();Batch的创建是通过createBatch()来创建的,createBatch()也是一个函数,看看它的源码:
/** @private Generate a new standard 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,
httpMethod:dwr.engine._httpMethod,
async:dwr.engine._async,
timeout:dwr.engine._timeout,
errorHandler:dwr.engine._errorHandler,
warningHandler:dwr.engine._warningHandler,
textHtmlHandler:dwr.engine._textHtmlHandler
};
if(batch.xml==null)
{
batch.xml="aaa";
}
if (dwr.engine._preHook) batch.preHooks.push(dwr.engine._preHook);
if (dwr.engine._postHook) batch.postHooks.push(dwr.engine._postHook);
var propname, data;
if (dwr.engine._headers) {
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;
};
里面有很多信息,重要的就是Batch这个变量,里面定义了很多内容。如果对javascript不是很了解,就会感到很茫然,为什么这么说呢?请看下面定义的形式:
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,
httpMethod:dwr.engine._httpMethod,
async:dwr.engine._async,
timeout:dwr.engine._timeout,
errorHandler:dwr.engine._errorHandler,
warningHandler:dwr.engine._warningHandler,
textHtmlHandler:dwr.engine._textHtmlHandler
};
这里面定义的形式类似于一个键一个值(举例textHtmlHandler键:dwr.engine._textHtmlHandler值),这也是javascript中创建一个对象的一种方式,我们也可以通过这种方式来创建,我们可以把这种方式想象成一个键对应一个值,这就是一个对象当中的属性和属性对应的值。也可以想象成dom编程的方式,也就是文档对象模型,为什么可以想象成文档对象模型呢,这就是元素和元素中的内容。怎么想象都可以,但是这种方式我们要注意学习学习。说说里面的内容,创建batch(批处理),批处理可能很多次都要调用到,所以需要一个变量callCount:0指定批处理中需要调用多少次,初始化为0;page是指定请求的页面,window.location.pathname只的是请求的路径,window.location.search指的是路径问号(?)后面的信息; httpSessionId就是JSESSIONID;scriptSessionId 脚本SessionId
分享到:
相关推荐
### DWR源码分析与应用解析 #### DWR框架简介 DWR,全称为Direct Web Remoting,是一款轻量级的远程调用框架,旨在简化Web应用中的JavaScript与Java之间的通信。通过DWR,开发者可以直接从JavaScript调用服务器端...
DWR (Direct Web Remoting) 是一个开源的Java库,它允许JavaScript在浏览器端与服务器端的Java对象进行交互,实现动态的Web应用。DWR简化了AJAX(Asynchronous JavaScript and XML)的开发,使得开发者可以像调用...
在这个压缩包中,包含了一系列关于DWR技术分析、学习资料以及相关的界面开发内容,对于理解和掌握DWR技术至关重要。 首先,DWR的XML配置文件是连接客户端与服务器端的关键,它定义了哪些Java对象和方法可以被...
dwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwrdwr dwr
通过分析这些文件,我们可以深入了解DWR如何与HTML、JavaScript配合,实现实时的数据交互和二级联动下拉列表的功能。 总结来说,利用Ajax和DWR框架实现的二级联动下拉列表,使得用户可以在不刷新页面的情况下完成...
在IT领域的开发中,利用DWR(Direct Web Remoting)框架结合Ajax技术实现二级菜单的联动,是一项常见的功能需求,尤其是在动态网页应用中。本文将深入解析如何在包含Spring、Hibernate、Ajax、DWR等技术栈的项目中,...
DWR (Direct Web Remoting) 是一个开源框架,它允许JavaScript在浏览器端直接调用Java方法,从而实现AJAX的应用。DWR的核心功能是通过自动转换Java对象为JavaScript对象,使得前端可以像操作本地对象一样操作远程...
Direct Web Remoting (DWR) 是一个开源的Java库,它允许在Web应用程序中实现实时的Ajax通信。DWR简化了JavaScript与服务器端Java对象之间的交互,使得开发者可以像调用本地方法一样调用远程服务。在这个入门例子中,...
二、DWR工作原理 1. **反向Ajax**:DWR实现了一种反向Ajax(Reverse Ajax)技术,使得服务器能够主动向客户端推送数据,而不仅仅是响应客户端的请求。 2. **JavaScript与Java的桥接**:DWR通过动态生成JavaScript库...
DWR的使用流程** 1. **引入DWR库**:在Web应用中添加DWR的JAR文件,并在Web.xml中配置DWR的Servlet。 2. **创建Java接口**:定义要在客户端使用的Java接口,这些接口将被DWR暴露给JavaScript。 3. **生成配置文件**...
同时,DWR提供了丰富的API和工具,简化了前后端的交互流程,提高了开发效率。 在实际项目中,将dwr.jar添加到项目的类路径中,然后在web.xml中配置DWR的servlet,最后根据项目需求调整dwr.xml文件,就可以开始利用...
4. **DWR的运行流程**: - 浏览器加载HTML页面,执行JavaScript代码。 - JavaScript通过DWR发起HTTP请求到服务器。 - DWR Engine接收到请求后,根据`dwr.xml`配置调用相应的Java方法。 - 服务器执行Java方法,...
通过分析这个war文件,开发者可以学习如何配置DWR的XML配置文件(dwr.xml),以及如何创建可从JavaScript调用的Java方法。 3. **DWR2.0中文说明文档**: 这份文档对于理解DWR的工作原理和使用方法至关重要,特别是...
Direct Web Remoting (DWR) 是一个开源的Java库,它允许JavaScript在浏览器端与服务器端的Java对象进行交互,实现Ajax应用。这个"dwR练习实例(各种数据转换list,map,数组等)"是一个用于学习DWR如何处理和转换不同...
DWR(Direct Web Remoting)是一种Java库,它允许JavaScript在客户端与服务器端进行直接的交互,从而实现在Web应用程序中的Ajax功能。DWR的主要目标是简化前后端的数据交换,提高用户体验,使得Web应用能够像桌面...
3. **DWR映射**:学习如何定义`dwr.xml`配置文件,将前端JavaScript对象映射到后端Java类和方法,这是DWR工作流程的关键部分。 4. **基本使用**:教程可能会涵盖如何创建第一个DWR调用,包括异步和同步调用,以及...
**DWR配置文件详解** Direct Web Remoting (DWR) 是一种开源的Java库,它允许Web应用程序在客户端JavaScript和服务器端Java之间进行双向通信。DWR的核心配置文件是`dwr.xml`,该文件定义了DWR允许访问的Java对象、...
**DWR技术分析** 1. **异步通信**:DWR利用AJAX技术实现页面无刷新更新,用户可以即时看到服务器端的反馈,提升了交互体验。 2. **安全控制**:DWR提供了安全性控制机制,例如使用白名单限制可调用的Java方法,...