关于Spring , Struts结合学习 - - BlogJava

来源:百度文库 编辑:神马文学网 时间:2024/07/03 09:00:48
关于Spring , Struts结合学习
关于Spring , Struts结合学习。
一、前言
刚刚接触了日本一个项目,用的框架名称是Northland Framework,主要用到以下部分
Struts、Spring、iBATIS、Velocity。Struts、Spring如何结合在一起?
二、 Spring 提供了三种整合 Struts 的方法:
使用 Spring 的 ActionSupport 类整合 Structs
使用 Spring 的 DelegatingRequestProcessor 覆盖 Struts 的 RequestProcessor
将 Struts Action 管理委托给 Spring 框架
( 参见 Get a better handle on Struts actions, with Spring
http://www-128.ibm.com/developerworks/java/library/j-sr2.html?ca=drs-tp4105
对应还有译文:
http://gocom.primeton.com/modules/techresource/article504.htm?utm_campaign=searchengine&utm_source=baidu&utm_medium=jjpm&utm_term=Spring+Struts )
三、我只关心第三种整合方法:
这种方法通过 Spring 提供的两个和 Struts 相关类来实现: org.springframework.web.struts. DelegatingActionProxy , org.springframework.web.struts. ContextLoaderPlugIn 。
ContextLoaderPlugIn 实现 Struts 的 PlugIn 接口,只要在 struts-config.xml 中有如下配置:
< action     path = "/searchSubmit" >
type = "ca.nexcel.books.actions.DelegatingActionProxy"
input = "/searchEntry.do"
validate = "true"
name = "searchForm" >
< forward name = "success" path = "/WEB-INF/pages/detail.jsp" />
< forward name = "failure" path = "/WEB-INF/pages/search.jsp" />

< plug-in className = "org.springframework.web.struts.ContextLoaderPlugIn" >
< set-property property = "contextConfigLocation" value = "/WEB-INF/beans.xml" />

ActionServlet 装载的时候就可以顺便装载和 Spring 相关的 beans.xml ,和 beans.xml 中相关的一个东西叫做 WebApplicationContext , ( 在 Spring 里关键就是取得 WebApplicationContext ,取得这个也就可以用 Spring 管理业务 ) ,在 ContextLoaderPlugIn 中是这样保存 WebApplicationContext :
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
再看 DelegatingActionProxy ,它继承于 Struts 的 Action ,以后 struts-config.xml 中所有的
Action-mapping 都要指向它,只是每个 Action-mapping 的 path 不同,将来也是用这个 path 来区分究竟需要执行 beans.xml 中的那个类。如下代码:
public ActionForward execute(){
Action delegateAction = getDelegateAction(mapping);
return delegateAction.execute(mapping, form, request, response);
}
这里的 delegateAction 就是 beans.xml 中一个相关的类 (beans.xml 也要求类继承于 Struts 的 Action) 去看看怎么得到 delegateAction :
protected Action getDelegateAction(ActionMapping mapping) throws BeansException {
WebApplicationContext wac = getWebApplicationContext(getServlet(),
mapping.getModuleConfig());
String beanName = determineActionBeanName(mapping);
return (Action) wac.getBean(beanName, Action.class);
}
是如何取得 WebApplicationContext 呢:
wac=(WebApplicationContext)actionServlet.getServletContext().getAttribute(        ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX);
SERVLET_CONTEXT_PREFIX 正是 前边提到的 ContextLoaderPlugIn 中 的 attrName 。
现在这个原理一目了然, ContextLoaderPlugIn 在 actionServlet 初始化过程中保存
起来留到后面供 DelegatingActionProxy 用。
四、在另一篇文章中提到在上面的方法中 OpenSessionInView Filter 不能用
( 参照http://wyyhzc.itpub.net/) ,这个东西我也不熟悉,是不是有不少 Spring 的东西在这种方式中都不能用呢? 这就说到另一种取得 Spring WebApplicationContext 的方法:
在 web.xml 中配置 ContextLoaderListener :
< context-param >
< param-name > contextConfigLocation
< param-value >
/WEB-INF/beans.xml


< listener >
< listener-class > org.springframework.web.util.Log4jConfigListener

< listener >
< listener-class > org.springframework.web.context.ContextLoaderListener

对应的 beans.xml 和前边那个一样, Log4jConfigListener 先不用管,去查看相关文档。
Web 服务启动的时候,我们去看看 ContextLoaderListener 作了什么:
WebApplicationContext = createWebApplicationContext(servletContext, parent);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
同样是保存 WebApplicationContext ,但是 key 是 ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
怎么才能不用 ContextLoaderPlugIn 而只用 ContextLoaderListener ? 下面我修改
org.springframework.web.struts. DelegatingActionProxy 把它修改成
ca.nexcel.books.actions. DelegatingActionProxy 并且修改一下代码:
修改 getWebApplicationContext 方法
Return DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet,
moduleConfig); 换成下边方法
ServletContext sc = actionServlet.getServletContext();
WebApplicationContext wac = null;
wac = WebApplicationContextUtils.getWebApplicationContext(sc);
return wac;
并且在 struts-config.xml 中将 action 的 type 指向自己的
ca.nexcel.books.actions. DelegatingActionProxy , PlugIn 删除 web.xml 加上刚才提到的 Listener ,启动 tomcat 运行一切正常。
五、我把 northland 的配置文件贴出来。
Struts-config.xml :
< action-mappings >
< action
path = "/list"
input = "/list.jsp"
name = "_list"
scope = "request"
type = "jp.co.nec.hnes.northland.web.struts.FlowAction"
>
< display-name > 一覧画面

< action
path = "/register"
input = "/register.jsp"
name = "_register"
scope = "request"
type = "jp.co.nec.hnes.northland.web.struts.FlowAction"
>
< display-name > 登録画面

Web.xml:
< context-param >
< param-name > contextConfigLocation
< param-value >
classpath:flowConfig.xml,
classpath:viewConfig.xml,
classpath:applicationContext.xml,
classpath:applicationContext-extra.xml


< listener >
< listener-class > org.springframework.web.util.Log4jConfigListener

< listener >
< listener-class > org.springframework.web.context.ContextLoaderListener

< servlet >
< servlet-name > ActionServlet
< servlet-class > org.apache.struts.action.ActionServlet
< init-param >
< param-name > config
< param-value > /WEB-INF/struts-config.xml


从中可以看到
其中的 jp.co.nec.hnes.northland.web.struts.FlowAction 和
ca.nexcel.books.actions. DelegatingActionProxy 的功能差不多。