本文摘自:http://slei.net 在LiferayPortal中使用DWR Portal的概念风风火火地炒了好几年,确始终没有大红大紫。眼看着Ajax和Web2.0朝自己杀来,靠Portal产品过日子的厂商们也终于按耐不住了。老牌开源Portal产品Liferay在其4.0版本中就加入了Ajax的东东,其Portlet的移动、添加和删除就是基于Ajax的。但是这远远是不够的,如果不能在产品级别更好的支持Portlet内部的Ajax,那么传统的Portal很可能会穷途末路,因为完全基于Ajax的PortalFramework已经出现了,如Light。 然而无论Ajax和Web2.0发展成什么样,有一点它是无法取代Portal的,就是Web系统的组件化乃至服务化。Portal最有价值的地方也就是提出了把Web系统当作组件或服务来集成,这样,无论是遗留下来的Web系统,还是新开发的Web系统,都可以很简单地集成在一块儿,并且,把某个Web系统替换掉也是很简单的。也许不久的将来,Ajax和Web2.0的阵营中也会出现把Web系统当作组件或服务的技术,但是这其实就是Portal的概念,换汤不换药。 前阵子有机会在LiferayPortal下开发一些Ajax的Portlet,其中用到了DWR,有些tricky的地方,写在这里方便各位,也方便自己。 在Portlet的jsp中引用DWR的js不能简单地直接使用相对路径,比如,如果DWR的js相对jsp放在/dwr目录中的话,如下的引用方式是不对的: <scripttype="text/javascript"src="/dwr/engine.js"></script> <scripttype="text/javascript"src="/dwr/util.js"></script> <scripttype="text/javascript"src="/dwr/interface/YourClass.js"></script> 因为当你把Portlet部署到Liferay的时候,这个相对路径的意义就变了。为了正确引用js,我们必须使用如下的声明方式: <scripttype="text/javascript" src='<%=renderResponse.encodeURL(renderRequest.getContextPath()+"/dwr/engine.js")%>'> </script> <scripttype="text/javascript" src='<%=renderResponse.encodeURL(renderRequest.getContextPath()+"/dwr/util.js")%>'> </script> <scripttype="text/javascript" src='<%=renderResponse.encodeURL(renderRequest.getContextPath()+ "/dwr/interface/RSSReader.js")%>'> </script> <scripttype='text/javascript'src='/dwr/interface/SelectProductTypeSearch.js'></script> <scripttype='text/javascript'src='/dwr/interface/SelectSchoolBuildingSearch.js'></script> <scripttype='text/javascript'src='/dwr/engine.js'></script> <scripttype='text/javascript'src='/dwr/util.js'></script> 其中的renderRequest和renderResponse是LiferayPortal添加到jsp中的隐含变量,负责对Portlet进行渲染。renderRequest.getContextPath()就是当前jsp的路径,加上js相对于jsp的路径,最后要用renderResponse.encodeURL()方法解码一下才能得到正确的路径。 其他方面,DWR的使用方法就和在一般的jsp中的使用方法一样了。从这里也可以看出,不光是使用DWR,所有对js及其他资源的引用都要用这种方法。 如何实现DWR的多人同时开发 这几天研究了一下DWR,觉的有了这个东东后,Ajax就非常Easy了,可以说是不用学了,我用的是1.1.1的版本,2.0的版本目前还在开发,具体的网址是http://getahead.ltd.uk/dwr/documentation,里面说的很简单,对Web开发比较熟的化,一天就能全学会,不过要做好的话,还是需要在工作中遇到具体的问题再具体解决,再和Spring和Hibernate一结合的化,感觉能大大加快开发进度,现在主要说说如何配置多个dwr.xm,这样的化就可以多个人同时开发,互不影响,这对公司的版本控制还是比较有益处的. 主要是在web.xml中配置 <servlet> <servlet-name>dwr-user-invoker</servlet-name> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> <init-param> <param-name>config-user</param-name> <param-value>WEB-INF/dwr-user.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet> <servlet-name>dwr-admin-invoker</servlet-name> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> <init-param> <param-name>config-admin</param-name> <param-value>WEB-INF/dwr-admin.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dwr-admin-invoker</servlet-name> <url-pattern>/dwradmin/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>dwr-user-invoker</servlet-name> <url-pattern>/dwruser/*</url-pattern> </servlet-mapping> 这样的话在WEB-INF文件夹下就新增两个XML文件,分别为dwr-user.xml,dwr-admin.xml就行了,然后访问:http://localhost:8080/yourapp/dwruser就能看到它的测试页面了,把它的javascript文件的存放位置拷下来,放到你的JSP或html文件中,就OK了,我觉的这个测试页主要也就是做这个的,它的一些测试方法,我觉的不是很好用.这样就可以同时有多个XML的配置文件,大家同时开发不影响. 最后记住一点,为了搞明白这一点,花了我一下午和晚上的时间,就是在你的webapp目录中,不要创建dwruser或dwradmin这样的目录,更不要把Jsp或html放进去,否则的话,不管用绝对还是相对路径都找不到.
<scripttype='text/javascript'src='/dwr/dwr/interface/JDate.js'></script> <scripttype='text/javascript'src='/dwr/dwr/engine.js'></script> <scripttype='text/javascript'src='/dwr/dwr/util.js'></script> dwr的页面必须放在根文件么?(20分)
所属论坛:Web开发Ajax 发表时间:2006-8-1211:07:19
配置如下: 1.xml文件 <?xmlversion="1.0"encoding="UTF-8"?> <web-appversion="2.4"xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> </web-app> 2.dwr.xml <?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEdwrPUBLIC"-//GetAheadLimited//DTDDirectWebRemoting1.0//EN""http://www.getahead.ltd.uk/dwr/dwr10.dtd"> <dwr> <allow> <createcreator="new"javascript="FirstAjax"> <paramname="script"value="com.ajax.start.FirstAjax"/> </create> <createcreator="new"javascript="DwrTest"> <paramname="class"value="com.ajax.start.DwrTest"/> <paramname="script"> <![CDATA[ com.ajax.start.DwrTest; returnDwrTest.getInstance(); ]]> </param> <includemethod="getMessage"/> </create> </allow> </dwr> 3.index.html <html> <head> <title>nowstartajax</title> <Metahttp-equiv="Content-Type"content="text/html;charset=iso-8859-1"/> <scripttype="text/javascript"src="./dwr/interface/FirstAjax.js"></script> <scripttype="text/javascript"src="./dwr/engine.js"></script> <scripttype="text/javascript"src="./dwr/util.js"></script> <scripttype="text/javascript"src="./dwr/interface/DwrTest.js"></script> <scripttype="text/javascript"> functionsendMessage(msg) { alert("123"); varmsgvalue=document.getElementById(msg).value; FirstAjax.getGreetings(loadMessage,msgvalue); } functionloadMessage(data) { document.getElementById("message").innerHTML=data; } functiongetMessage(){ DwrTest.getMessage(load,1); } functionload(data){ document.getElementById("message").innerHTML=data; varrow=createElement("tr"); varnodetext=create } </script> </head> <body> <h2>ajaxiscoming....</h2> <table> <tr> <td>following...</td> </tr> <tr> <td> <inputtype="text"name="msg"size="30"> <inputtype="button"value="clickme"name="tt"onclick="sendMessage('msg')"> <inputtype="button"value="test1"name="tt"onclick="getMessage()"> </td> </tr> <tr> <td> <divid="message"></div> </td> </tr> </table> </body> </html> 目录结构: webroot/WEB-INF/WEB.XML webroot/WEB-INF/DWR.XML webroot/admin/index.html dwr测试页测试DwrTest方法正常,但在index.html上却提示DwrTest未定义。把index.html放在webroot/目录下能正常显示。求解
第1楼 2006-8-1211:15:00返回顶部
...... <scripttype="text/javascript"src="../dwr/interface/FirstAjax.js"></script> <scripttype="text/javascript"src="../dwr/engine.js"></script> <scripttype="text/javascript"src="../dwr/util.js"></script> <scripttype="text/javascript"src="../dwr/interface/DwrTest.js"></script> 原来是这样,结帖 ———————————————————————— AJAX,可不是荷兰阿贾克斯足球队,是一种利用XMLHTTP请求的技术,本文介绍DWR实现AJAX的框架。 1,获取dwr.jar http://www.getahead.ltd.uk/dwr/download.html 获得的dwr.jar放到WEB-INF/lib目录下 2,配置web工程的web.xml文件 <servlet> <servlet-name>dwr-invoker</servlet-name> <display-name>DWRServlet</display-name> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping>
3,创建一个dwr.xml文件,放在WEB-INF目录下和web.xml做伴 <dwr> <allow> <createcreator="new"javascript="JDate"> <paramname="class"value="java.util.Date"/> </create> <createcreator="new"javascript="Demo"> <paramname="class"value="your.java.Bean"/> </create> </allow> </dwr>
4,按照指示,此时运行http://localhost:8080/YOUR_APP/dwr应该出现一个页面,但是我运行的时候出错了,原因是dwr.xml文件缺点东西。 改为: <?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEdwrPUBLIC "-//GetAheadLimited//DTDDirectWebRemoting1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd"> <dwr> <allow> <createcreator="new"javascript="JDate"> <paramname="class"value="java.util.Date"/> </create> <createcreator="new"javascript="JString"> <paramname="class"value="java.lang.String"/> </create> </allow> </dwr>
看到这个界面,我忽然有一个伟大的想法了!如果把jdk常用的类配置到这里,那么我们就可以很very方便的查看jdkAPI各个方法的运行结果了哈。
关于dwr.dtd的说明,请参考 http://www.getahead.ltd.uk/dwr/server/dwrxml.html 【注意】如果你使用的是dwr0.8.x版本,这样写可能不对。我现在用的是0.9.2b版本。 5,点击页面列出的Jdate,可以查看java.util.Date()各个方法的输出,这是怎么实现的呢?查看一下源码,有几个很重要的地方。 <SCRIPTsrc="/ept/dwr/interface/JDate.js"type=text/javascript></SCRIPT> <SCRIPTsrc="/ept/dwr/engine.js"type=text/javascript></SCRIPT> <SCRIPTsrc="/ept/dwr/util.js"type=text/javascript></SCRIPT>
6,自己完整编写一个例子: 引用地址:http://yhe.dl.cn/html/trackback.do?log_id=178&type=1(复制地址) 技术文摘|评论(7)|阅读(1797)|Trackback(0)|
≡≡≡网友评论≡≡≡ 小红帽网友说:2005/12/2916:14
建议看看这个http://www.amowa.net/buffalo_bak 198181网友说:2005/12/2916:12
老实说,ajax还没有一个大众都可以去接受的“标准”框架。 这个框架也不太好用。 happy网友说:2005/11/2516:43
为什么我在自己机器上装了可以用,装到另外一台机器就抱dwrutil未定义的错误啊 happy网友说:2005/11/2516:35
sdf 阿獠二网友说:2005/07/1811:38
lodestar51网友说:2005/07/1321:17
前几天下载.看了一下DEMO,不太明白.以后向你学习.. 小红帽网友说:2005/07/0710:18
其他资源: AJAXmadesimplewithDWR http://www.javaworld.com/javaworld/jw-06-2005/jw-0620-dwr_p.html http://www.getahead.ltd.uk/dwr/ Ajax的一些资源汇总 http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=11362&threadID=23813&messageID=140065 ———————————————————————————————————————————— DWR(DirectWebRemoting)是一个WEB远程调用框架.利用这个框架可以让AJAX开发变得很简单.利用DWR可以在客户端利用JavaScript直接调用服务端的Java方法并返回值给JavaScript就好像直接本地客户端调用一样(DWR根据Java类来动态生成JavaScrip代码).它的最新版本DWR0.6添加许多特性如:支持DomTrees的自动配置,支持Spring(JavaScript远程调用springbean),更好浏览器支持,还支持一个可选的commons-logging日记操作. 以上摘自open-open,看了几天,确实是一个非常优秀的项目,它通过反射,将java翻译成javascript,然后利用回调机制,轻松实现了javascript调用Java代码。 其大概开发过程如下: 1.编写业务代码,该代码是和dwr无关的。 2.确认业务代码中哪些类、哪些方法是要由javascript直接访问的。 3.编写dwr组件,对步骤2的方法进行封装。 4.配置dwr组件到dwr.xml文件中,如果有必要,配置convert,进行java和javascript类型互转。 5.通过反射机制,dwr将步骤4的类转换成javascript代码,提供给前台页面调用。 5.编写网页,调用步骤5的javascript中的相关方法(间接调用服务器端的相关类的方法),执行业务逻辑,将执行结果利用回调函数返回。 6.在回调函数中,得到执行结果后,可以继续编写业务逻辑的相关javascript代码。 下面以用户注册的例子,来说明其使用。(注意,本次例子只是用于演示,说明DWR的使用,类设计并不是最优的)。 1.先介绍下相关的Java类 User:用户类, publicclassUser{ //登陆ID,主键唯一 privateStringid; //姓名 privateStringname; //口令 privateStringpassword; //电子邮件 privateStringemail;
//以下包含getXXX和setXXX方法 ....... } UserDAO:实现User的数据库访问,这里作为一个演示,编写测试代码 publicclassUserDAO{ //存放保存的数据 privatestaticMapdataMap=newHashMap(); //持久用户 publicbooleansave(Useruser){ if(dataMap.containsKey(user.getId())) returnfalse; System.out.println("下面开始保存用户"); System.out.println("id:"+user.getId()); System.out.println("password:"+user.getPassword()); System.out.println("name:"+user.getName()); System.out.println("email:"+user.getEmail()); dataMap.put(user.getId(),user); System.out.println("用户保存结束"); returntrue; } //查找用户 publicUserfind(Stringid){ return(User)dataMap.get(id); } } DWRUserAccess:DWR组件,提供给javascript访问的。 publicclassDWRUserAccess{ UserDAOuserDAO=newUserDAO(); publicbooleansave(Useruser){ returnuserDAO.save(user); } publicUserfind(Stringid){ returnuserDAO.find(id); } }
下面说明下程序执行的流程 1.用户在页面上输入相关注册信息,id、name、password、email,点击“提交”按钮 2.javascript代码开始执行,根据用户填写相关信息,通过dwr提供的DWRUserAccess.js里save的方法,调用服务器端的DWRUserAccess类save方法,将注册信息保存。 3.通过DWRUserAccess.jsp里的find方法,调用服务器端DWRUserAccess类里的find方法,执行用户信息查找。 注意,在以上的执行过程中,DWRUserAccess是供DWR调用的,是DWR组件,因此需要将DWRUserAccess类配置到dwr中。 接下来讲解本次dwr测试环境的配置。 1.新建一个webapp,命名为testApp 2.将dwr.jar拷贝到testApp的WEB-INF的lib目录下 3.编译上面的User,UserDAO,DWRUserAccess类,放到classes目录下 4.在web.xml中配置servlet,适配路径到dwr目录下,如下所示 <servlet> <servlet-name>dwr-invoker</servlet-name> <display-name>DWRServlet</display-name> <description>DirectWebRemoterServlet</description> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>scriptCompressed</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> 以上的配置可以拦截testApp下所有指向dwr的请求,关于这个拦截器,我们会在后面介绍。 5.WEB-INF下新建一个dwr.xml文件,内容如下: <?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEdwrPUBLIC"-//GetAheadLimited//DTDDirectWebRemoting1.0//EN""http://www.getahead.ltd.uk/dwr/dwr10.dtd"> <dwr> <allow> <createcreator="new"javascript="DWRUserAccess"> <paramname="class"value="test.DWRUserAccess"/> </create> <convertconverter="bean"match="test.User"/> </allow> </dwr> 这里我们把DWRUserAccess配置到了dwr中,create元素中,creater="new"表示每调用一次DWRUserAccess时,需要new一个这样的类;javascript="DWRUserAccess",表示提供给前台页面调用的javascirpt文件是DWRUserAccess.js。 convert元素用于数据类型转换,即java类和javascript之间相互转换,因为和前台交换的是User对象,因此需要对此使用bean转换,我们将在后面介绍这个类。 4.编写测试的HTML页面test.html <!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN"> <HTML> <HEAD> <TITLE>DWR测试</TITLE> <Metahttp-equiv=Content-Typecontent="text/html;charset=gb2312"> <scriptsrc="/oblog312/dwr/engine.js"></script> <scriptsrc="/oblog312/dwr/util.js"></script> <scriptsrc="/oblog312/dwr/interface/DWRUserAccess.js"></script> </HEAD> <BODY> <B>用户注册</B><br> ------------------------------------------------ <Br> <formname="regForm"> 登陆ID:<inputtype="text"name="id"><br> 口令:<inputtype="password"name="password"><br> 姓名:<inputtype="text"name="name"><br> 电子邮件:<inputtype="text"name="email"><br> <inputtype="button"name="submitBtn"value="提交"onclick="OnSave()"><br> </form> <br> <br><B>用户查询</B><br> ------------------------------------------------ <Br> <formname="queryForm"> 登陆ID:<inputtype="text"name="id"><br> <inputtype="button"name="submitBtn"value="提交"onclick="OnFind()"><br> </form> <br> </BODY> </HTML> <SCRIPTLANGUAGE="JavaScript"> <!-- functionsaveFun(data){ if(data){ alert("注册成功!"); }else{ alert("登陆ID已经存在!"); } } functionOnSave(){ varuserMap={}; userMap.id=regForm.id.value; userMap.password=regForm.password.value; userMap.name=regForm.name.value; userMap.email=regForm.email.value; DWRUserAccess.save(userMap,saveFun); } functionfindFun(data){ if(data==null){ alert("无法找到用户:"+queryForm.id.value); return; } alert("找到用户,\nid:"+data.id+",\npassword:"+data.password+",\nname:"+data.name+",\nemail:"+data.email); } functionOnFind(){ DWRUserAccess.find(queryForm.id.value,findFun); } //--> </SCRIPT>
|