使用 ActionForm
當客戶請求交給了 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擔任以下的幾個職責:
- 填寫表單欄位至表單物件屬性中
- 客戶資料的緩衝區
- 進行資料完整性、格式驗證
- 進行屬性值的轉換
- 進行資料安全性驗證,阻止惡意資料進入應用程式
=================================================================================
=>LoginAction<=
package onlyfun.caterpillar;
import java.util.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.util.MessageResources;
import org.apache.commons.beanutils.PropertyUtils;
public class LoginAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
String username = (String) PropertyUtils.getSimpleProperty(form,"username");
String password = (String) PropertyUtils.getSimpleProperty(form,"password");
request.setAttribute("username", username);
if (username.equals("caterpillar") && password.equals("1234")) {
return mapping.findForward("helloUser");
}
Map<String, String> msgModel = new HashMap<String, String>();
MessageResources messageResources = (MessageResources) getResources(request);
msgModel.put("namePasswordMismatched", messageResources.getMessage("message.namePasswordMismatched"));
request.setAttribute("messages", msgModel);
return mapping.findForward("loginFail");
}
}
=>struts-config.xml<=
<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" validate="true" input="/WEB-INF/pages/fail.jsp">
<forward name="helloUser" path="/WEB-INF/pages/hello.jsp" />
<forward name="loginFail" path="/WEB-INF/pages/fail.jsp" />
</action>
</action-mappings>
<message-resources parameter="onlyfun.caterpillar.ApplicationResources" />
</struts-config>
=>fail.jsp<=
<html>
<head>
<title>Sorry!</title>
</head>
<body>
<H1>
${errors["invalidUsername"]}invalidUsername......
<br>
${errors["invalidPassword"]}invalidPassword......
<br>
${messages["namePasswordMismatched"]}namePasswordMismatched.......
</H1>
<p><a href='/va/html/form.htm'>Login</a>
</body>
</html>
=>UserForm<=
package onlyfun.caterpillar;
import java.util.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.Globals;
import org.apache.struts.util.MessageResources;
public class UserForm extends ActionForm {
private static final long serialVersionUID = 1L;
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 req) {
username = null;
password = null;
}
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {
Map<String, String> errModel = new HashMap<String, String>();
MessageResources messageResources=(MessageResources)request.getAttribute(Globals.MESSAGES_KEY);
if(getUsername() == null || getUsername().length() < 1){
String msg = messageResources.getMessage("error.invalidUsername");
errModel.put("invalidUsername", msg);
}
if(getPassword() == null ||getPassword().length() < 1){
String msg = messageResources.getMessage("error.invalidPassword");
errModel.put("invalidPassword", msg);
}
if(errModel.get("invalidUsername") == null && errModel.get("invalidPassword") == null){
System.out.println("1");
return null;
}else {
/**
* 必须与显示该信息的名字相同errors,
* 例如fail.jsp页面的${errors["invalidUsername"]}
*/
request.setAttribute("errors", errModel);
ActionErrors errors = new ActionErrors();
/**
* 返回ActionMessages.GLOBAL_MESSAGE为键名的ActionErrors对象
*/
errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(""));
return errors;
}
}
}
=>form.htm<=
<html>
<head>
<title>Login</title>
</head>
<body>
Please login:
<p>
<form name="userForm" action="/va/login.do" method="post">
username
<input type="text" name="username" />
<br>
password
<input type="password" name="password" />
<p>
<input type="submit" />
</form>
</body>
</html>
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)