首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

运用ActionSupport代替Action

2012-09-02 
使用ActionSupport代替Action有一种方法可以用于Spring与Struts的整合:让Action在程序中手动获得Applicati

使用ActionSupport代替Action

有一种方法可以用于Spring与Struts的整合:让Action在程序中手动获得ApplicationContext实例。在这种整合策略下,Struts的Action不接受IoC容器管理,Action的代码与Spring API部分耦合,造成代码污染。
这种策略也有其好处:代码的可读性非常强,Action的代码中显式调用业务逻辑组件,而无需等待容器注入。
Action中访问ApplicationContext有两种方法:
1.利用WebApplicationContextUtils工具类
2.利用ActionSupport支持类

WebApplicationContextUtils可以通过ServletContext获得Spring容器实例。ActionSupport类则提一个更简单的方法:getWebApplicationContext(),该方法用于获取ApplicationContext实例。
Spring扩展了Struts的标准Action类,Spring的Action在Struts的Action后加上Suppport,Spring的Action有如下:
1.ActionSupport。
2.DispatchActionSupport。
3.LookupDispatchActionSupport。
4.MappingDispatchActionSupport。

下面分别给出利用ActionSupport的示例代码:
新的业务控制器,继承Spring的ActionSupport类

public class LoginAction extends ActionSupport {//依然将ValidBean作为成员变量private ValidBean vb;//构造器,注意:不可在构造器中调用getWebApplicationContext()方法public LoginAction(){}//完成ValidBean的初始化public ValidBean getVb(){   return (ValidBean)getWebApplicationContext().getBean("vb");}    //必须重写该核心方法,该方法actionForm将表单的请求参数封装成值对象    public ActionForward execute(ActionMapping mapping, ActionForm form,       HttpServletRequest request, HttpServletResponse response)throws Exception{   //form由ActionServlet转发请求时创建,包装了所有的请求参数   LoginForm loginForm = (LoginForm)form;   //获取username请求参数   String username = loginForm.getUsername();   //获取pass请求参数   String pass = loginForm.getPass();   //下面作服务器端的数据校验   String errMsg = "";   //判断用户名不能为空   if (username == null || username.equals(""))   {    errMsg += "您的用户名丢失或没有输入,请重新输入";   }   //判断密码不能为空   else if(pass == null || pass.equals(""))   {    errMsg += "您的密码丢失或没有输入,请重新输入";   }   //如果用户名和密码不为空,才调用业务组件   else   {    //vb是业务逻辑组件,通过上面的初始化方法获得    if (getVb().valid(username,pass))    {     return mapping.findForward("welcome");    }    else    {     errMsg = "您的用户名和密码不匹配";    }   }   //判断是否生成了错误信息,   if (errMsg != null && !errMsg.equals(""))   {    //将错误信息保存在request里,则跳转到input对应的forward对象    request.setAttribute("err" , errMsg);    return mapping.findForward("input");   }   else   {    //如果没有错误信息,跳转到welcome对应的forward对象    return mapping.findForward("welcome");   }    }}
?

?

这种整合策略下,表现层的控制器组件不再接受IoC容器管理。因此没有了控制器context,应将原有的action-servlet.xml文件删除,并修改plug-in元素,不要加载该文件。还要修改action配置,将action配置的type元素修改成实际的处理类。这种整合策略也有个好处:代码可读性更强,对传统Struts应用开发的改变很小,容易使用。
将该Action部署在struts-config.xml中,Struts将负责创建该Action。struts-config.xml文件的源代码如下:

<!-- XML文件版本,编码集--><?xml version="1.0" encoding="gb2312"?><!-- struts配置文件的文件头,包括dtd等信息--><!DOCTYPE struts-config PUBLIC          "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"          "http://struts.apache.org/dtds/struts-config_1_2.dtd"><!-- struts配置文件的根元素--><struts-config><!-- 配置formbean,所有的formbean都放在form-beans元素里定义--><form-beans>   <!-- 定义了一个formbean,确定formbean名和实现类-->   <form-bean name="loginForm" type="lee.LoginForm"/></form-beans><!-- 定义action部分,所有的action都放在action-mapping元素里定义--><action-mappings>   <!-- 这里只定义了一个action。action的类型为ActionSuport的子类 -->   <action path="/login" type="type="lee.LoginAction"    name="loginForm" scope="request" validate="true" input="/login.jsp" >    <!-- 定义action内的两个局部forward元素-->    <forward name="input" path="/login.jsp"/>    <forward name="welcome" path="/welcome.html"/>   </action></action-mappings><!-- 加载国际化的资源包--><message-resources parameter="mess"/><!--- 装载验证的资源文件--><plug-in className="org.apache.struts.validator.ValidatorPlugIn">   <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />   <set-property property="stopOnFirstError" value="true"/></plug-in></struts-config>
?


此时,Spring无需使用配置Action的配置文件,这种配置方式非常简单。只需要业务逻辑组件的配置文件,业务逻辑组件的配置文件如下:

<?xml version="1.0" encoding="gb2312"?><!-- 指定Spring 配置文件的dtd><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd"><!-- spring配置文件的根元素 --><beans><!-- 配置ValidBean实例--><bean id="vb" class="lee.ValidBeanImpl"/></beans>
?

?

该配置文件中的业务逻辑组件由于Spring容器负责实现,而ActionSupport能够先定位Spring容器,然后获得容器的业务逻辑组件。
这种整合策略的执行效果与前面两种整合策略的执行效果完全相同。
从代码中分析,在这种整合策略下,业务控制器再次退回到Struts起初的设计:仅由struts-config.xml中Action充当,而避免了像DelegatingActionProxy整合策略的性能低下,因为可以只需要创建实际的Action实例。
这种整合策略的代价是代码污染。

热点排行