ITEEDU

Struts Gossip: 使用 ActionForm

ActionForm是窗体的对象化表示,它本身设计为JavaBean,您要继承org.apache.struts.action.ActionForm来设计一个窗体对象,并提供标准的getter与setter方法,必要时可以使用继承下来的reset()、validate()等方法供 Struts 组件呼叫。

当客户请求交给了 RequestProcessor 后,RequestProcessor会从 ActionMapping 中得知所使用的ActionForm对象,这是在struts-config.xml中设定的,如果所需的ActionForm还不存在就生成一个,之后一直使用它,ActionMapping与ActionForm对象会被当作参数传递给 Action

在Struts 1.1中,ActionForm生成之后,会执行RequestProcessor的processPopulate()方法,首先它会呼叫 ActionForm的reset()方法,您可以在当中作一些重清ActionForm属性的动作,然后窗体的参数值会与ActionForm的 setter进行比对,如果有名称符合的就将窗体的参数值设定给对应的属性。

透过继承ActionForm类别来使用它,下面是一个简单的例子:
UserForm.java
package onlyfun.caterpillar; 

import javax.servlet.http.*;
import org.apache.struts.action.*;

public class UserForm extends ActionForm {
private String username;
private String password;

public void setUsername(String username) {
this.username = username;
}

public void setPassword(String password) {
this.password = password;
}

public String getUsername() {
return username;
}

public String getPassword() {
return password;
}

public void reset(ActionMapping mapping,
HttpServletRequest request) {
username = null;
password = null;
}
}
必须在struts-config.xml中定义Action对象使用哪一个ActionForm对象:
struts-config.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">

<struts-config>
    <form-beans>
        <form-bean
            name="userForm"
            type="onlyfun.caterpillar.UserForm"/>
    </form-beans>

    <action-mappings>
        <action
            path="/login"
            type="onlyfun.caterpillar.LoginAction"
            name="userForm">
            <forward
                name="helloUser"
                path="/WEB-INF/pages/hello.jsp"/>
            <forward
                name="loginFail"
                path="/WEB-INF/pages/fail.jsp"/>
        </action>
    </action-mappings>
</struts-config> 
 
在这个例子中,<form-bean>卷标定义了所使用的ActionForm对象及其名称userForm,而在< action>标签的设定中,LoginAction指定了userForm作为其所使用的ActionForm, LoginAction类别如下:
LoginAction.java
package onlyfun.caterpillar;

import javax.servlet.http.*;
import org.apache.struts.action.*;

public class LoginAction extends Action {
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
String username = ((UserForm) form).getUsername();
String password = ((UserForm) form).getPassword();

request.setAttribute("username", username);

if(username.equals("caterpillar") &&
password.equals("1234")) {
return mapping.findForward("helloUser");
}

return mapping.findForward("loginFail");
}
}
ActionForm被作为参数传递至execute()方法,在验证使用者的名称与密码无误后,查找helloUser的 ActionForward对象并传回,这会使得RequestProcessor将请求转发至hello.jsp:
hello.jsp
<html> 
<head>
<title>Hello, ${username} !</title>
</head>
<body>
<H1>Hello, ${username} !</H1>
<H1>This is your secret gift!!</H1>
</body>
</html>
如果验证失败,则查找loginFail的ActionForward对象并传回,也就是fail.jsp:
fail.jsp
<html> 
<head>
<title>Sorry!</title>
</head>
<body>
<H1>Sorry, ${username} !</H1>
<H1>You must provide correct login information!!</H1>
<p>
<a href='/strutsapp/html/form.htm'>Login</a>
</body>
</html>

最后是一个简单的登入窗体,这是个静态HTML,放在/strutsapp/html下就可以了:
form.htm
<html> 
<head><title>Login</title></head>
<body>
   Please login:<p>
    <form name="userForm" action="/strutsapp/login.do" method="post">
   username <input type="text" name="username"/><br>
   password <input type="password" name="password"/><p>
        <input type="submit"/>
    </form>
</body>
</html>
ActionForm在Struts中是属于View组件的一部份,它是对象化的窗体,窗体的参数会自动设定给 ActionForm,无法对应的就加以忽略,在ActionForm中您可以填入窗体值,作一些适当的值转换,进行基本的数据验证, ActionForm可以作为窗体数据发送至应用程序前的缓冲区,在某些程度上,它是应用程序的防火墙,您可以在ActionForm中避免不正确或不安 全的数据进入应用程序。

综合一下,ActionForm担任以下的几个职责:
  • 填写窗体字段至窗体对象属性中
  • 客户数据的缓冲区
  • 进行数据完整性、格式验证
  • 进行属性值的转换
  • 进行数据安全性验证,阻止恶意数据进入应用程序