messagekey="pass"/>passwordproperty="pass"/>
submit>messagekey="login"/>
submit>
form>
在浏览器中浏览该页面时,看到该页面包含了一个简单的登录表单。
该页面的界面如图3.1所示。
该页面中有两个表单域,这两个表单域封装了需要向服务器发送的请求参数,对于Strurts应用而言,请求参数是通过ActionForm来封装的,ActionForm非常类似一个POJO(定义几个属性,为每个属性提供setter和getter方法),但该ActionFrom需要继承ActionForm,或者是它的子类。
因为本应用使用了Struts的校验框架,因此本应用中的ActionForm继承了ValidatorForm类。
下面是本应用中ActionForm类的代码:
publicclassLoginFormextendsValidatorForm
{
//下面两个属性用于封装两个表单域的请求参数
privateStringusername;
privateStringpass;
//以下是属性字段的系列get、set方法
publicStringgetUsername()
{
returnusername;
}
publicvoidsetUsername(Stringusername)
{
this.username=username;
}
publicStringgetPass()
{
returnpass;
}
publicvoidsetPass(Stringpass)
{
this.pass=pass;
}
}
上面ActionForm类的代码非常简单,除了该类需要继承ValidatorForm之外。
也正是因为该ActionForm继承了ValidatorForm,从而导致了该类的污染,降低了该类的代码复用。
对于Struts1而言,ActionForm类是一个既烦琐又没有技术含量的类,写起来难免让程序员觉得意兴索然。
虽然有很多IDE(集成开发环境)可以自动生成该ActionForm类,但Struts1框架也感觉到大量重复书写该类是一个负担,后来提供了动态ActionForm,让人可以避免书写ActionForm类。
注意Struts1中的ActionForm类是一个非常简单的类,它实质上是一个普通的JavaBean,但必须继承ActionForm类。
除此之外,ActionForm还可以使用动态FormBean,从而允许通过配置文件来定义ActionForm。
3.1.3实现Action
Action就是用于处理用户请求的业务控制器,当用户请求发送到ActionServlet后,ActionServlet拦截到用户请求,将请求转发到系统的业务控制器处理。
ActionServlet在转发用户请求时,会将请求参数封装成ActionForm实例,并将该ActionForm实例转发给Action实例。
Action实例从ActionForm中取出用户请求参数,然后调用业务逻辑组件处理用户请求,并根据处理结果,调用不同的视图页面来呈现处理结果。
下面是系统的Action处理类代码。
publicclassLoginActionextendsAction
{
//必须重写该execute方法,该方法用于处理用户请求
publicActionForwardexecute(ActionMappingmapping,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)throws
Exception
{
//获取封装用户请求参数的ActionForm实例
LoginFormloginForm=(LoginForm)form;
//从ActionForm中取出用户请求参数
Stringusername=loginForm.getUsername();
Stringpass=loginForm.getPass();
//处理用户请求
if(username!
=null&&username.equals("scott"))
{
returnmapping.findForward("welcome");
}
else
{
returnmapping.findForward("error");
}
}
}
上面的Action代码非常简单,甚至没有调用任何业务逻辑组件,只是直接判断用户请求参数的用户名和密码是否为scott和tiger,如果用户名和密码正确,则返回welcome的ActionForward,否则返回error的ActionForward。
注意ActionForward就是一个逻辑视图,通过在配置文件中定义ActionFoward的映射,完成逻辑视图名和实际视图资源之间的映射。
Struts1的Action类与Struts2的Action类有一定的类似性,都通过调用execute方法来处理用户请求。
但最大的区别在于Struts1Action的execute方法与ServletAPI耦合,但Struts2Action类的execute方法无需与ServletAPI耦合。
3.1.4配置Struts1的Action
实现了Struts1的Action后,还需要在struts-config.xml文件中配置Action,配置Action需要指定Action的实现类,以及Action处理请求的URL。
配置Action时,还应该配置该Action对应的ActionForm,每个ActionForm使用一个元素定义。
定义Action和ActonForm之间的关联关系时,在定义Action的元素中通过name属性指定与此Action关联的ActionForm。
因为本应用还使用了Struts1的数据校验框架,因此配置元素时,还应该增加validate属性,并将该属性值设置成true;还需要增加input属性,该属性指向输入校验失败后转入的视图资源。
下面是本应用的struts-config.xml文件代码。
xmlversion="1.0"encoding="GBK"?
>
--指定Struts1配置文件的DTD信息-->
DOCTYPEstruts-configPUBLIC
"-//ApacheSoftwareFoundation//DTDStrutsConfiguration1.2//EN"
"http:
//struts.apache.org/dtds/struts-config_1_2.dtd">
--指定Struts1配置文件的根元素-->
--所有的ActionForm都应该在form-beans元素中定义-->
--每个form-bean定义一个ActionForm-->
--所有的Action都放在action-mappings元素中定义-->
--定义Action,其处理类为lee.LoginAction,对应的ActionForm为
loginForm-->
validate="true"scope="request"input="/login.jsp">
--当返回welcome的ActionForward时,转入welcome.jsp页-->
--当返回error的ActionForward时,转入error.jsp页-->
--加载国际化资源文件-->
--加载Struts1校验框架的插件-->
--指定数据校验的两个校验规则文件-->
/WEB-INF/validation.xml"/>
正如前面看到的,页面中使用大量国际化标签来输出国际化消息,因此本应用必须加载相应的国际化资源文件,本应用的国际化资源文件的baseName是MyResource。
指定应用的国际化资源文件通过元素指定。
本应用使用了Struts1的校验框架来完成输入校验,因此在本应用中加载了两个校验规则文件,其中validator-rules.xml文件是一个系统规则文件,通常无需修改;validation.xml文件是开发者定义的规则文件,该文件定义了需要校验的表单应该满足的规则。
下面是校验规则文件的代码。
xmlversion="1.0"encoding="GBK"?
>
--校验规则定义文件-->
DOCTYPEform-validationPUBLIC"-//ApacheSoftwareFoundation
//DTDCommonsValidatorRulesConfiguration1.1.3//EN"
"http:
//jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">
--校验规则文件的根元素-->
--定义需要校验的ActionForm,定义该ActionForm为loginForm-->
--定义username表单域必须满足必填、模式匹配两个规则-->
--指定模式匹配在正则表达式-->
mask
^\w+$
--定义pass表单域必须满足必填、最小长度两个规则-->
--定义最小长度的规则-->
minlength}"resource="false"
position="1"/>
minlength
4
上面的规则文件定义了表单域的两个表单必须满足的规则:
username是必填的,而且必须匹配^\w+$的正则表达式;pass是必填的,并且至少有4位。
定义了上面的校验规则后,如果用户的输入不能通过该输入校验,则系统自动转入配置元素时指定的input属性所对应的视图资源。
输入校验的提示信息都保存在国际化资源文件中,因此使用输入校验时,通常都建议使用国际化资源文件来保存校验提示信息。
提示使用输入校验时,通常建议使用国际化资源文件来保存校验失败的提示信息。
3.1.5完成应用流程
经过上面步骤,可以非常清楚地看出上面示例应用的流程,用户进入系统的login.jsp页面,用户输入请求信息,发送请求。
如果用户的请求参数不能通过输入校验,则系统将请求转发到login.jsp页面,否则请求将被转发到业务逻辑控制器Action处。
Action处理用户请求参数,如果处理结果为success的ActionForward,则进入welcome.jsp页面;如果处理结果为error的ActionForward,则进入error.jsp页面。
图3.2显示了该应用的顺序图。
图3.2系统顺序图
如果用户输入的用户名正确、密码正确,用户登录成功,可以在welcome.jsp页面见到国际化的欢迎信息,并且通过Struts1的标签输出登录的用户名。
下面是welcome.jsp页面的代码。
<%@pagecontentType="text/html;charset=gb2312"errorPage="error.jsp"%>
--导入Struts的三个标签库-->
<%@includefile="taglibs.jsp"%>
--通过Struts1标签输出国际化的页面标题-->
messagekey="loginSuccess"/>
messagekey="loginSuccess"/>