ActionForm Bean的基本应用
(一) 什么是ActionForm
ActionForm Bean就是Struts框架中的一个JavaBean,用来获取用户提交的Html表单中的数据。ActionForm在Struts框架中是一个非常重要的角色,它在把前台表单数据提交给Action处理前表单域封装成Bean对象。
自定义的ActionForm继承Struts框架的ActionForm基类org.apache.struts.action.ActionForm,其代码结构由三部分组成:
1、 属性对象对应的getter()、setter()方法
2、 validate()方法(可选)
3、 reset()方法(可选)
(二) 如何使用ActionForm
如果在Struts中要使用ActionForm的功能,那么自定义的ActionForm必须继承Struts框架的ActionForm基类,并有选择的重写validate()和reset()方法。
1、 重新ActionForm中的reset()方法,完成数据的初始化
reset()方法在把用户提交的表单数据封装成ActionForm前对域属性进行初始化。根据不同的用户请求的作用域不同,操作稍微有所不同。
当struts-config.xml中对应的<action>元素的scope属性为request时,用户的每个新请求都会创建新的实例,且实例创建后,就首先调用reset()方法进行属性的默认初始值设置。由于在创建ActionForm实例过程中,属性已经被初始化为默认值,因此就不用再调用reset()方法进行默认值设置,即该方法可以不重写或者只写一个空的方法体。
当scope属性为session时,同一个ActionForm实例会被某个用户的多个请求所共享,这时就必须重写reset()方法,手动设置属性的默认值。重写代码如下:
===========================================================
//重写的reset()方法:
- public void reset(ActionMapping mapping,HttpServletRequest request)
- {
- this.userName=null;
- this.userPassword=null;
- }
===========================================================
2、 重写ActionForm中的validate()方法,完成数据的有效性校验。
===========================================================
//重写的validate()方法:
- public ActionErrors validate(ActionMapping mapping,HttpServletRequest request)
- {
- ActionErrors errors = new ActionErrors();
- if(userName=="")
- {
- errors.add("userNameError",new ActionMessage("nameNull"));
- }
- if(userPassword=="")
- {
- errors.add("userPassword",new ActionMessage("passwordNull"));
- }
- return errors;
- }
===========================================================
3、 修改struts-config.xml文件,使validate()方法生效。
===========================================================
//struts-config.xml文件中的配置:
- <action path="/login" name="loginForm" type="com.phome.struts1.action.LoginAction" validate="true" scope="request" input="/login.jsp">
1、Struts1框架的ActionServlet控制器根据struts-config.xml文件的配置找到注册的对应的action;
2、根据ActionForm的作用域(scope)的范围查找相应的ActionForm实例(如果找不到就创建一个新的ActionForm实例并添加到相应的作用域);
3、得到ActionForm实例后,就调用reset方法(如果没有重写该方法,就调用父类的reset()方法,父类中的方法是一个空方法体);
4、将用户提交的表单中的数据封装到ActionForm中。
scope="request"每次提交都生成一个新的actionform对象,而 scope="session"时,再一次绘画中生成一个actionform对象,保存在session中,获取时从session中获取。 scope决定actionform的生命周期。
大多数情况用request。也有特殊情况用session。如表单跨页Prj8_1
Forward类型的action只负责跳转打包不做其他事情
<action name="reg1Form" forward="/P2.jsp" path="/toP2" scope="session">
<set-property property="cancellable" value="true" />
</action>
<action name="reg1Form" path="/reg1" type="prj8_1.action.Reg1Action" scope="session">
<set-property property="cancellable" value="true" />
</action>
注意两个scope都是session,否则前两个的值保留不住。
验证时用隐藏表单域的方法验证。
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
// TODO Auto-generated method stub
if (page.equals("1")) {
if (account.length() == 0) {
}
if (password.length() == 0) {
}
}
if (page.equals("2")) {
if (phone.length() == 0) {
}
if (address.length() == 0) {
}
}
return null;
}
其中page属性就是被隐藏的属性在表单中用<html:hidden property="page" value=""/>用value的值来区别开来。
//
比如有的页面有三个电话提交时我们可以将他们分别定义成三个属性,但这样造成ActionForm属性太多;我们也可以将其定义为一个数组属性,即String[] phones;这样跳转回来的话有个问题就是三个文本框里会出现[Ljava.lang.String;@17e4dee这是由于它将整个数组返回来了,解决的办法就是<html:text property="phones" value=""/>使其变为空,但很难让他们各填各值。另外还可以利用索引属性,实现如下
ActionForm中的属性是随着i而变化的
String[] phones = new String[3];
public String getPhones(int i) {
return phones[i];
}
public void setPhones(int i, String phone) {
this.phones[i] = phone;
}
JSP
<html:form action="/reg3">
phone1:<html:text property="phones[0]"></html:text><br>
phone2:<html:text property="phones[1]"></html:text><br>
phone3:<html:text property="phones[2]"></html:text><br>
<html:submit/><html:cancel/>
</html:form>
Action
Reg3Form reg3Form = (Reg3Form) form
for (int i = 0; i < 3; i++) {
System.out.println(reg3Form.getPhones(i));
}
return new ActionForward("/reg3.jsp");
第三种方法可以使text中的文本保持住。
但是我们可以看到上面这种方法也有一种缺陷,就是你必须知道个数,但能够接受。可以用arraylist,但是顺序没有保障,所以不推荐。