论坛首页 Web前端技术论坛

Struts2.0与 DWR2.0 的整和

浏览 24404 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-07-05  
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就可以了

 

<init-param></init-param>最后有一点很重要,就是在 web.xml文件中配置DwrServlet 的时候一定要加上 
     <param-name></param-name> exposeInternals
     <param-value></param-value> true
      

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

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


   发表时间:2007-07-05  
其实 ,Servlet那层,可以扔掉了。

不要在再Web层还用  XX+XX。
0 请登录后投票
   发表时间:2007-07-06  
对,采用dwr,可以直接去访问业务层,不用采用Struts 之类的,但有些时候还需要控制层,在个别的地方的使用dwr去调用,两种结合着就比较好了.
0 请登录后投票
   发表时间:2007-07-07  
请教楼主:

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的配置:
<!DOCTYPE dwr PUBLIC
    "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
    "http://getahead.ltd.uk/dwr/dwr20.dtd">
<dwr>
    <allow>
        <create creator="spring" javascript="inquiryMasterAction">
            <param name="class" value="cn.net.cogent.summer.webapp.action.InquiryMasterAction"/>
            <param name="beanName" value="inquiryMasterAction"/>
            <include method="getDetailsByMasterId"/>
        </create>
        <convert converter="bean" match="cn.net.cogent.summer.model.InquiryDetail"/>
    </allow>
</dwr>


其中InquiryMasterAction的getDetailsByMasterId方法的Java代码为:
public List<InquiryDetail> getDetailsByMasterId(Long masterId);


生成的inquiryMasterAction.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 (inquiryMasterAction == null) var inquiryMasterAction = {};
inquiryMasterAction._path = '/dwr';
inquiryMasterAction.getDetailsByMasterId = function(p0, callback) {
  dwr.engine._execute(inquiryMasterAction._path, 'inquiryMasterAction', 'getDetailsByMasterId', p0, callback);
}


在JSP页面中只需要调用:
<script type='text/javascript'>
  var masterId = 1;
  var result;
  inquiryMasterAction.getDetailsByMasterId(1, result);
</script>
0 请登录后投票
   发表时间:2007-07-07  
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 的调用都可以通过
DWRActionUtil.execute({
  namespace:'/yournamespace',
  action:'yourAction',
  method:'yourMethod',
  executeResult:'true'
}, 'data', callBack);  

这种方式去调用就可以了,这个方法最终会去调用 DWRAction.js里的execute()方法。这种方式是保留了Action的原汁原味,按照Struts2的机制去处理的。
具体的你可以参考一下 dwr2的文档中 与webwork整和的部分或着参考下面的
http://wiki.javascud.org/display/dwrcn/WebWork+Integration?focusedCommentId=917506
也可以
0 请登录后投票
   发表时间:2007-07-07  
to swimren:

谢谢你的热心指点,你提到的这种方式确实能与Struts 2更自然地结合,值得深入学习!
0 请登录后投票
   发表时间:2007-08-17  
按照你的方式还是不行啊,DWRAction类还是有错,可以提供代码么?
0 请登录后投票
   发表时间:2007-08-25  
客户端如果需要直接使用JSON格式的数据,DWR还能用吗?我现在改用控制器输出JSON数据。
0 请登录后投票
   发表时间:2007-09-21  
http://kkbear.iteye.com/admin/show/125130
0 请登录后投票
   发表时间:2007-12-04  
我还是不赞成hack源码。

现在,我们都是用maven来管理jar包,hack源码的风险太大。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics