本站不再更新,欢迎光临 java开发技术网
随笔-230  评论-230  文章-8  trackbacks-0

转自于:http://swimren.javaeye.com/blog/98186

关键字: DWR       

最近发现dwr出了2.0版本,里面提供了与目前一些主流框架的整合,如Spring,JSF,Hibernate,Struts1,Webwork等,但Struts2.0还没有提供,由于现在的项目我们采用的是Struts2.0,所以参考dwr与webwork的整合代码,修改完成了
dwr与Struts2的整和代码

1、首先下载Dwr2的源代码,将 org\directwebremoting\webwork下的类拷出来,放到 新建的一个包
   比如 org.dwr.struts2 里,接下去就可以去修改里面的代码,
    将类的引用都修改为从struts2的包中引用。
2、接下去关键是修改 DWRAction.java这个类
   在该类中 比较特殊的是
   com.opensymphony.webwork.dispatcher.DispatcherUtils
对应的struts2中的  org.apache.struts2.dispatcher.Dispatcher这个类
  ServletActionContext.WEBWORK_VALUESTACK_KEY  对应 ServletActionContext.STRUTS_VALUESTACK_KEY

3、修改里面的 private DWRAction(ServletContext servletContext) 构造函数为

java 代码
  1. private DWRAction(ServletContext servletContext) throws ServletException   
  2.     {   
  3.        // Dispatcher.initialize(servletContext);   
  4.         m_wwDispatcher = Dispatcher.getInstance();   
  5.         if(m_wwDispatcher==null)   
  6.         {   
  7.            m_wwDispatcher = new Dispatcher(servletContext, new HashMap());   
  8.            m_wwDispatcher.init();   
  9.            Dispatcher.setInstance(m_wwDispatcher);   
  10.         }   
  11.            
  12.         m_actionProcessor = loadActionProcessor(servletContext.getInitParameter         (DWRACTIONPROCESSOR_INIT_PARAM));   
  13.     }   

然后修改protected ActionInvocation invokeAction 方法 将第126行的代码

java 代码
  1. ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(actionDefinition.getNamespace(), actionDefinition.getAction(), extraContext, actionDefinition.isExecuteResult(), false);   

替换为以下代码

java 代码

 

  1. Configuration config = du.getConfigurationManager().getConfiguration();   
  2.             ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(   
  3.                     mapping.getNamespace(), mapping.getName(), extraContext, actionDefinition.isExecuteResult(), false);   

最后将 protected void prepareContinuationAction(HttpServletRequest request, Map extraContext)
 里的代码都注释掉 就可以了

4,修改 DWRActionUtil.js文件将里面的webwork字样都替换为 struts2,也可以不用修改,不过觉得不爽就是了
  然后就可以按照与webwork整和的方式配置dwr.xml就可以了

 

最后有一点很重要,就是在 web.xml文件中配置DwrServlet 的时候一定要加上 
     exposeInternals
     true
      

这个参数,否则生成的 DWRAction.js 这个文件将不存在 DWRAction.execute(actionObj, params, callbackObj) 这个函数,这个问题折磨了我近半天的时间啊.

如果需要可以提供代码上来,不过最好还是建议大家亲自去修改一下比较好.


最后更新:2007-07-07 11:10
17:17  |   永久链接  |   浏览 (994)  |   评论 (5)  |    收藏  |   AJAX  |   进入论坛  |  
评论    共 5 条 发表评论
totodo     2007-07-05 20:35

其实 ,Servlet那层,可以扔掉了。

不要在再Web层还用 XX+XX。

swimren     2007-07-06 08:23

对,采用dwr,可以直接去访问业务层,不用采用Struts 之类的,但有些时候还需要控制层,在个别的地方的使用dwr去调用,两种结合着就比较好了.

movingboy     2007-07-07 00:06

请教楼主:

1.我现在在试用AppFuse 2.0-M5,我尝试了它自带的DWR 2.0.1和Struts 2.0.6,在客户端能够正确地调用Struts action的方法并返回数据。我看了DWRAction.java的代码,确实是象你提到的改动前的样子,但我没做任何改动。我想问一下你改动这个类的目的是什么呢?不改动会有什么问题呢?

2.你在文中提到:

引用
最后有一点很重要,就是在 web.xml文件中配置DwrServlet 的时候一定要加上
exposeInternals
true

 

我的web.xml没有设置这一项。如果没有生成DWRAction.execute(actionObj, params, callbackObj) ,会有什么问题呢?

附上我的例子作为分析参考:
dwr.xml的配置:

代码
  1. <!DOCTYPE dwr PUBLIC   
  2.     "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"   
  3.     "http://getahead.ltd.uk/dwr/dwr20.dtd">  
  4. <dwr>  
  5.     <allow>  
  6.         <create creator="spring" javascript="inquiryMasterAction">  
  7.             <param name="class" value="cn.net.cogent.summer.webapp.action.InquiryMasterAction"/>  
  8.             <param name="beanName" value="inquiryMasterAction"/>  
  9.             <include method="getDetailsByMasterId"/>  
  10.         </create>  
  11.         <convert converter="bean" match="cn.net.cogent.summer.model.InquiryDetail"/>  
  12.     </allow>  
  13. </dwr>  

 

其中InquiryMasterAction的getDetailsByMasterId方法的Java代码为:

代码
  1. public List<InquiryDetail> getDetailsByMasterId(Long masterId);  

 

生成的inquiryMasterAction.js的内容:

代码
  1. // Provide a default path to dwr.engine   
  2. if (dwr == null) var dwr = {};   
  3. if (dwr.engine == null) dwr.engine = {};   
  4. if (DWREngine == null) var DWREngine = dwr.engine;   
  5.   
  6. if (inquiryMasterAction == null) var inquiryMasterAction = {};   
  7. inquiryMasterAction._path = '/dwr';   
  8. inquiryMasterAction.getDetailsByMasterId = function(p0, callback) {   
  9.   dwr.engine._execute(inquiryMasterAction._path, 'inquiryMasterAction', 'getDetailsByMasterId', p0, callback);   
  10. }   

 

在JSP页面中只需要调用:

代码
  1. <script type='text/javascript'>  
  2.   var masterId = 1;   
  3.   var result;   
  4.   inquiryMasterAction.getDetailsByMasterId(1, result);   
  5. </script>  

 

swimren     2007-07-07 10:57

to movingboy :

我没有具体的去研究 AppFuse 2.0-M5的源码,不过从你的描述中可以看出来,你的这种配置方式也是可以正常工作的。
首先你是 把InquiryMasterAction 看作一个独立的类来处理的,也就是说针对 InquiryMasterAction 单独生成了一个inquiryMasterAction.js文件,而方法getDetailsByMasterId 返回的是你实际需要的数据。然后再通过
inquiryMasterAction.getDetailsByMasterId(1, result); 去调用的,这种方式是DWR最初的最简单方式。你的例子里实际上是没有用到 DWRAction.js这个文件和DWRAction.java这个类了。
但是在Struts2中,Action 中的方法是需要具体的返回一个String类型的 result,也就是定位到具体的页面或路径上。而需要的数据都被放到 ValueStack中了。所以数据的取法就不一样了。
上面说的dwr2与strut2的整和,主要是为了不需要调整原来的Action的写法。所有的Action 的调用都可以通过

代码
  1. DWRActionUtil.execute({   
  2.   namespace:'/yournamespace',   
  3.   action:'yourAction',   
  4.   method:'yourMethod',   
  5.   executeResult:'true'   
  6. }, 'data', callBack);     

这种方式去调用就可以了,这个方法最终会去调用 DWRAction.js里的execute()方法。这种方式是保留了Action的原汁原味,按照Struts2的机制去处理的。
具体的你可以参考一下 dwr2的文档中 与webwork整和的部分或着参考下面的
http://wiki.javascud.org/display/dwrcn/WebWork+Integration?focusedCommentId=917506
也可以
posted on 2007-07-23 13:20 有猫相伴的日子 阅读(8571) 评论(8)  编辑  收藏 所属分类: dwr

评论:
# re: dwr2与struts2整合[未登录] 2007-11-02 17:09 | aa
还用struts+dwr 直接访问 service
  回复  更多评论
  
# re: dwr2与struts2整合 2009-01-03 21:53 | 肖亮亮
经过一般研究,修改修改
DWRActionUtil.js里报错,stactk overflow at line 28
DWRActionUtil.js的内容
/*
* Copyright 2005 Joe Walker / Alexandru Popescu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* Declare an object to which we can add real functions.
*/
if (dwr == null) var dwr = {};
if (dwr.struts2 == null) dwr.struts2 = {};
if (DWRActionUtil == null) var DWRActionUtil = dwr.struts2;

/** Execute a remote request using DWR */
dwr.struts2.execute = function(action, values, callbackObjOrName) {
var params = {};
if (dwr.struts2.isElement(values)) {
var element = $(values);

var elementName= element.nodeName.toLowerCase();
if (elementName == 'form') {
for (var i = 0; i < element.elements.length; i=i+1) {
var e = element.elements[i];
if (e.name != null && e.name != '') params[e.name] = dwr.util.getValue(e);
}
}
else {
params[element.name] = dwr.util.getValue(element);
}
}
else {
for (var prop in values) {
params[prop]= values[prop];
}
}

// prepare action invocation object
var actionObj = {};
if (typeof action == 'string') {
var lastIdx= action.lastIndexOf('/');
actionObj.executeResult = 'true';
if (lastIdx != -1) {
actionObj.namespace = action.substring(0, lastIdx);
actionObj.action = action.substring(lastIdx + 1);
}
else {
actionObj.namespace= '';
actionObj.action = action;
}
}
else {
actionObj= action;
}

// prepare the DWR callback object
var callbackObj = {};
var mustCall= false;
if (typeof callbackObjOrName == 'string') {
callbackObj.callback = function(dt) { dwr.struts2.callback(dt, eval(callbackObjOrName)); };
mustCall= true;
}
else if (typeof callbackObjOrName == 'function') {
callbackObj.callback = function(dt) { dwr.struts2.callback(dt, callbackObjOrName); };
mustCall= true;
}
else if (typeof callbackObjOrName == 'object' && typeof callbackObjOrName.callback == 'function') {
for (var prop in callbackObjOrName) {
callbackObj[prop] = callbackObjOrName[prop];
}
callbackObj.callback = function(dt) { dwr.struts2.callback(dt, callbackObjOrName.callback); };
mustCall= true;
}
if (mustCall) {
dwr.struts2.execute(actionObj, params, callbackObj);
}
};

/** Execute a remote request using DWR */
dwr.struts2.callback = function(dt, originalCallback) {
if (dt.data) originalCallback(dt.data);
else if (dt.text) originalCallback(dt.text);
else originalCallback(dt);
};

/** Utility to check to see if the passed object is an input element / element id */
dwr.struts2.isElement = function(elementOrId) {
if (typeof elementOrId == "string") {
return true;
}
if (elementOrId.nodeName) {
var name= elementOrId.nodeName.toLowerCase();
if (name == 'input' || name == 'form') {
return true;
}
}

return false;
};
  回复  更多评论
  
# re: dwr2与struts2整合 2009-01-03 22:14 | 肖亮亮
我终于解决了,查了很多资料终于把dwr和s2整合  回复  更多评论
  
# re: dwr2与struts2整合 2010-12-25 10:55 | 看看你们
说直接掉业务层的应该直接说自己没学过编程  回复  更多评论
  
# re: dwr2与struts2整合[未登录] 2011-01-01 12:54 | 忧云
根本就不用那么麻烦的,我不知道你们用的struts2是什么版本的,我的是struts2-2.0.11.2,
在web.xml中加入:
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.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>


在dwr.xml中用spring注入bean:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
<dwr>
<allow>
<create creator="spring" javascript="acl">
<param name="beanName" value="aclService"/>
</create>
</allow>
</dwr>





dwr测试页面(呈现层用freemarker框架来显示html页面而没用jsp):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>dwr.html</title>

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type='text/javascript' src='/dwr/interface/acl.js'></script>
<script type='text/javascript' src='/dwr/engine.js'></script>
<script type='text/javascript' src='/dwr/util.js'></script>
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

</head>

<body>
<input type="button" value="DWR" onclick="dwrTest()"/>
</body>
<script type="text/javascript">
function dwrTest() {
acl.getString("前台",function(data){
alert(data);
});
}
</script>
</html>


这样就行了,是可以直接调用的。不知道你们为什么要改源码?搞了半天还不知道怎么回事,很多人还出现包冲突或版本不对。  回复  更多评论
  
# re: dwr2与struts2整合 2011-04-18 17:58 | Glorin
能够说具体些嘛?还是不怎么懂哈!@忧云
  回复  更多评论
  
# re: dwr2与struts2整合 2011-09-29 23:43 | 淡定
这话说的有点过了吧。有本事你自己去写一个框架,让大家来膜拜啊!  回复  更多评论
  
# re: dwr2与struts2整合[未登录] 2012-04-25 10:43 | libo
@肖亮亮
DWRActionUtil.js里报错,stactk overflow at line 28
请联系我QQ:635392334
非常感谢!!  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
本站不再更新,欢迎光临 java开发技术网