使用 DelegatingRequestProcessor(2)
ValidBeanlmpl是个业务逻辑bean,在本示例程序中仅作简单的判断,ValidBeanlmpl的源代码如下:
//面向接口编程,实现ValidBean 接口public class ValidBeanImpl implements ValidBean //根据输入的用户名和密码判断是否有效 public boolean valid(String username,String pass) //有效,返回trueif (username.equals("scott")&&pass.equals("tiger")) return true; return false; |
对原来的Action也作简单的修改,增加依赖注入所需的setter方法,使控制器依赖于业务逻辑组件。因为控制器本身没有逻辑能力,所以必须依赖于业务逻辑组件的计算结果决定返回值。
这样,程序的结果更加清晰化。修改后的Action源文件如下:
//业务控制器继承Actionpublic class LoginAction extends Action Ilaction控制器将调用的业务逻辑组件 private ValidBean vb; //依赖注入业务逻辑组件的setter方法。public void setVb(ValidBean vb) this.vb= vb; //必须重写该核心方法,该方法actionForm将表单的请求参数封 装成值对象public ActionForward execute (ActionMapping mapping,ActionFormform, HttpServletReq1吐estrequest, HttpServletResponse response)throws Exception Ilform由 Actionservlet转发请求时创建,包装了所有 的请求参数LoginForm loginForm = (LoginForm)form; //获取 username请求参数String username = loginForm‘getUsername(); //获取pass请求参数String pass = loginForm.getPass(); //下面作服务器端的数据校验 String errMsg = //判断用户名不能为空 i f(username == null I I username.equals("")) errMsg +=什忽的用户名丢失或没有输入,请重新输入"; //判断密码不能为空 else if (passnull// pass.equals(" ") ) errMsg += "您的密码丢失或没有输入,请重新输入"; //如果用户名和密码不为空,才调用业务组件 else //vb是业务逻辑组件,由容器注入 if(vb.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") ; |
由于增加了客户端数据校验,因此对 ActionForm 也应作简单修改,使 ActionForm不再继承原有的 ActionForm,而应继承 ValidatorActionForm。
为了完成数据校验,还应该编写数据校验规则文件。在 struts-config.xml 文件的尾部,有一个 plug-in 用来加载校验文件,其中 validator-rules.xml 文件位于 struts 压缩包的 lib下,直接复制过来即可使用,而 vali出tor.xml 必须自己编写,其 validator.xml 文件如下:
<?xml version="1.0" encoding="iso-8859-1"?> <!--验证规则文件的文件头,包括dtd等信息--> <!DOCTYPE form-validation PUBLIC '-//ApacheSoftwareFoundationllDTDCommons Validator RulesConfiguration 1.1.311EN"'' http://jakarta.apache.org/commons/dtds/ validator_l_l_3.dtd"><!--验证文件的根元素…〉 <form-validation><!--所奋需要验证的form都放在 formset里--〉 <formset> <!-- 需要验证的form名,该名与struts里配置的名相同--〉 <form name="loginForm"> <!-- 指定该 form的 username域必须满足的规则 必填,模式匹配> <field property="username" depends="required,mask"> carg key="loginForm.username" position="O"I>cvar> c! 句确定匹配模式的正则表达式->cvar-name>maskc/var-name> cvar-value>~[a-zA-Z]+$c/var-value>c/var>c/field>c!… 指定该 form 的 pass 域必须满足的规则:必填…〉 cfield property="pass" depends="required"> cmsg name="required" key="pass.required"l> carg key="loginForm.pass" position="O"I> elfield> c/fonn〉c/formset> c/form-validation〉 |
上面示例程序的结构非常清晰:表现层组件(action) 配置在 action-servlet.xml文件中:而业务逻辑层组件(vb) 配置在 applicationContext.xml文件中:如果应用中有DAO组件,可将该组件配置在dao-context.xml文件中,并将这三个文件放在plug-in元素里一起加载。
由于 DelegatingRequestProcessor会将请求转发到action,而该 action 已经处于 loC容器管理之下。因此,可以方便地访问容器中的其他bean。
通过配置文件可看出, action根本无需type属性,即 struts-config.xml中 action根本没有实例化,而是通过DelegatingRequestProcessor将请求转发给 Spring 容器中的同名bean。这种转发时机非常早,避免创建struts-config.xml配置文件中的action,因而性能非常好。采用这种整合策略的执行效果如图7.5 所示。
图 7.5 DelegatingRequestProcessor整合策 略登录失败的效果 |