2013年11月15日-DWR的工作原理
接触DWR有一段时间了,但是只是学会了怎么用,项目上能实现功能就得了,一直不知道它的实现原理,今天晚上花时间了解了一下它的实现原理。
1、首先,DWR是通过Servlet是实现的,所以我们在web.xml中需要配置一个DWRServlet类。这样所有的/dwr/*所有请求都由这个servlet来处理。
2、DWR给我们做了一件伟大的事情,就是将Java转换为了JavaScript,这一步通过dwr.xml配置文件实现。dwr.xml中有两个重要的概念需要说一下:
creator在dwr中主要的职责就是把用户发布在dwr.xml中的class进行实例化,这样js中就可以使用这个对象调用Java类中的方法了,实现了客户端和服务器端的通信;
DWR提供的creator包括:jsf,none,new,pageflow,spring,script,struts
最常用的就是new,也就是实例化一个对象。
converter的职责是在接受请求时把客户端的javascript对象转换成服务器端的java对象,通过调用发布的java bean后,在把返回的java的对象转化成javascript的对象给客户端调用。
DWR提供的converter包括:null,enum,primitive,bignumber,string,array,map,collection, date,dom,dom4j,jdom,xom,servlet,bean,object,hibernate
如果DWR提供的creator和convertor不能满足需求,用户也可以自己创建自己的creator和convertor,只要将其发布在dwr.xml中就行了。
理解了这两个概念就可以很容易的看懂dwr.xml的配置了。
3、接下来看一下解析之后的文件:
由于配置了/dwr路径,web.xml中配置的DWR的DwrServlet会处理请求,然后将engine.js以流的形式发送给浏览器,同时它还会自动生成Hello.js ,并同样以流的形式发送给浏览器,这两个文件都可以在浏览器的缓存里找到。这两个文件在工程中是找不到的,如果不明白DWR的原理,很容易去工程的路径下找文件,可以怎么也找不到。(我开始的时候就是 )
以上次DWR用法中的Hello为例子,在浏览器中访问目录/dwr/interface/Hello.js(如果去看更里面的servlet的代码,就可以发现/interface/是要求配置成这样的,固定的)可以看到解析后的代码:
if (typeof dwr == 'undefined' || dwr.engine == undefined) throw new Error('You must include DWR engine before including this file');(function() { if (dwr.engine._getObject("Hello") == undefined) { var p; p = {}; p._path = '/DWRDemo1/dwr'; /** * @param {class java.lang.String} p0 a param * @param {function|Object} callback callback function or options object */ p.sayHello = function(p0, callback) { return dwr.engine._execute(p._path, 'Hello', 'sayHello', arguments); }; /** * @param {function|Object} callback callback function or options object */ p.getName = function(callback) { return dwr.engine._execute(p._path, 'Hello', 'getName', arguments); }; /** * @param {class java.lang.String} p0 a param * @param {function|Object} callback callback function or options object */ p.setName = function(p0, callback) { return dwr.engine._execute(p._path, 'Hello', 'setName', arguments); }; dwr.engine._setObject("Hello", p); }})();