本文為原創,如需轉載,請注明作者和出處,謝謝!
<a href="http://blog.csdn.net/nokiaguy/archive/2008/04/14/2289760.aspx">《Struts 2系列教程》</a>
簡單驗證從本質上說就是在服務端來驗證用戶端送出的form中的資料。這種驗證隻是對form中的資料規則進行檢查,如必須輸入使用者ID,價格不能小于0或是對email格式的驗證。在這個驗證過程中,并不需要通路資料庫。是以,簡單驗證需要在使用者送出form後,并且在伺服器處理form中的資料之前進行。
在進行完簡單驗證後,如果form中的資料不合法,程式就會forward到指定的JSP頁(一般是包含form的頁面),并顯示相應的錯誤資訊。如果form中的資料完全正确,程式就會繼續執行。
一、在validate方法中進行簡單驗證
在上一篇文章中我們知道,Struts1.x通過ActionForm的子類來封裝了用戶端送出的form中的資料。而服務端程式隻需要通過ActionForm的子類的對象執行個體就可以通路form中的資料,而如果不使用ActionForm類,就必須通過request對象來獲得form中的資料。通過這種封裝機制可以使代碼更容易了解。然而,ActionForm類不僅可以封裝form中的資料,還可以通過ActionForm類的validate方法來驗證form中的資料。validate方法的定義如下:
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request)
當用戶端向服務端送出form後,Servlet引擎首先通過ActionForm的子類的對象執行個體裝載form中的資料,然後再調用validate方法進行驗證。validate方法傳回了一個ActionErrors對象。這個對象相當于一個Map,如果ActionErrors中沒有錯誤資訊,Servlet引擎就認為form中的資料是正确的,這時服務端程式就會繼續執行。如果ActionErrors中有錯誤資訊,程式就會跳轉到指定的錯誤頁面。下面讓我們通過一個完整的例子來示範一下如何通過validate方法來驗證form中的資料。實作這個例子需要如下五步:
【第1步】建立JSP頁面
在這一步将建立一個叫simpleValidation.jsp的頁面,這個JSP頁面用于采集使用者的輸入資訊。在<samples工程目錄>中建立一個simpleValidation.jsp檔案,并編寫如下的代碼:
<%@ page pageEncoding="GBK"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<html>
<head>
<title>注冊資訊(測試簡單驗證)</title>
<style type="text/css">
.text {
height: 20px;
width: 160px;
}
</style>
</head>
<body>
<html:form action="simpleValidation">
<table width="100%">
<tr>
<td align="right" width="45%"> 使用者名:</td>
<td width="55%">
<html:text property="user" styleClass="text" />
<font color="red"><html:errors property="errorUser" /></font>
</td>
</tr><tr /><tr />
<td align="right">登入密碼:</td>
<td>
<html:password property="password" styleClass="text" />
<font color="red"><html:errors property="errorPassword" /></font>
<td align="right">重複登入密碼:</td>
<html:password property="password1" styleClass="text" />
<font color="red"><html:errors property="errorPassword1" /></font>
<td align="right">電子郵件:</td>
<html:text property="email" styleClass="text" />
<font color="red"><html:errors property="errorEmail" /></font>
<td align="right"> <br> ${requestScope.success } </td>
<td align="left"> <br> <html:submit value=" 送出 " /> </td>
</tr>
</table>
</html:form>
</body>
</html>
在啟動Tomcat後,在IE的位址欄中輸入如下的URL:
<a href="http://localhost:8080/samples/simpleValidation.jsp">http://localhost:8080/samples/simpleValidation.jsp</a>
當通過上面的URL通路simpleValidation.jsp時,并不能正确顯示使用者資訊采集界面。原因是<html:form>标簽使用了一個simpleValidation,當JSP轉換成Servlet時,這個動作必須在struts-config.xml檔案中正确定義,否則将抛出一個javax.servlet.jsp.JspException異常。
【第2步】建立simpleValidation動作
由于本例的着重點是簡單驗證,是以,simpleValidation動作并不需要處理更多的工作。一個動作對應于一個動作類,這個動作類一般是org.apache.struts.action.Action類的子類。simpleValidation動作隻做如下兩項工作:
1. 設定驗證成功後,在目标頁中顯示的資訊字元串(儲存在request的屬性中)。
2.
跳轉到目标頁。
simpleValidation動作對應的動作類是SimpleValidationAction,在<samples工程目錄>"src"action目錄中建立一個SimpleValidationAction.java檔案,并輸入如下的代碼:
package action;
import javax.servlet.http.*;
import org.apache.struts.action.*;
public class SimpleValidationAction extends Action
{
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
request.setAttribute("success", "送出成功!"); // 設定在目标頁中顯示的資訊字元串
return mapping.findForward("simple"); // 跳轉到目錄頁(simple所指的JSP頁)
}
【第3步】建立ActionForm類
在這一步我們來建立一個用于接收有戶的送出資訊的ActionForm類:SimpleValidationForm。這個類從
org.apache.struts.action.ActionForm類繼承。在<samples工程目錄>
"src"actionform目錄中建立一個SimpleValidationForm.java檔案,代碼如下:
package actionform;
import javax.servlet.http.HttpServletRequest;
public class SimpleValidationForm extends ActionForm
// 以下四個變量分别對應于simpleValidation.jsp中的四個文本框中的值。
private String user;
private String password;
private String password1;
private String email;
public String getUser()
{
return user;
public void setUser(String user)
this.user = user;
public String getPassword()
return password;
public void setPassword(String password)
this.password = password;
public String getPassword1()
return password1;
}
public void setPassword1(String password1)
this.password1 = password1;
public String getEmail()
return email;
public void setEmail(String email)
this.email = email;
// 開始驗證使用者送出的資訊
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request)
ActionErrors error = new ActionErrors();
if (user.equals("")) // 必須輸入使用者名
error.add("errorUser", new ActionMessage("error.user.blank"));
if (password.equals("")) // 必須輸入密碼
error.add("errorPassword", new ActionMessage("error.password.blank"));
else if (!password.equals(password1)) // 兩個登入密碼必須一緻
error.add("errorPassword1", new ActionMessage("error.password1.confirmation"));
if (email.equals("")) // 必須輸入email
error.add("errorEmail", new ActionMessage("error.email.blank"));
else if (!email.matches("//w+(//.//w+)*@//w+(//.//w+)+")) // 驗證email的格式是否正确
error.add("errorEmail", new ActionMessage("error.email.invalid"));
// 傳回錯誤資訊,如果error中沒有錯誤資訊,
// 就會調用SimpleValidationAction類的對象執行個體來執行execute方法。
return error;
}
在編寫SimpleValidationAction類時應注意如下八點:
1. 要想在ActionForm類中進行驗證,必須在ActionForm類的子類中覆寫validate方法。
2. validate方法在ActionForm類的對象執行個體裝載完使用者送出的資料後調用,是以,在調用validate方法時,ActionForm類的屬性值已經是使用者送出的資訊了。是以可以直接使用這些屬性值進行驗證。
3. 在validate方法中驗證使用者送出的資料時,要使用ActionErrors類的執行個體對象傳回錯誤資訊
4. ActionErrors類的構造方法的第二個參是一個ActionMessage類的對象執行個體,而不是錯誤描述資訊。
5.ActionMessage類的構造方法的參數并不是錯誤描述資訊,而是錯誤描述資訊的key,具體的資訊在Java屬性檔案中(将在下一步實作)。
6. 使用ActionForm的屬性可以非常好地驗證字元串類型,但對于其他的資料類型(如整型)的某些驗證卻不太适合。如當使用者送出資料時,本該送出一個整數,但使用者卻送出了一個非整數資訊。對于這種情況,在ActionForm類的對象執行個體中這個使用者送出的資料的值為0。雖然使用ActionForm類的屬性無法準确驗證這種情況,但我們可以使用validate方法的第二個參數request的getParameter方法直接獲得用戶端送出的資料來進行驗證。
7. 如果ActionErrors對象中有錯誤資訊,在JSP中需要使用<html:errors>标簽顯示錯誤資訊。
8.
Struts實際上是将ActionErrors對象以org.apache.struts.action.ERROR作為鍵值儲存在了request的
屬性中。是以,<html:errors>标簽實際上是從request的屬性中獲得的錯誤資訊描述。如我們也可以通過如下的Java代碼來
獲得produceID屬性的錯誤描述資訊:
<%
java.util.Iterator<org.apache.struts.action.ActionMessage> it =
((org.apache.struts.action.ActionErrors)request
.getAttribute("org.apache.struts.action.ERROR")).get("productID");
out.println(((org.apache.struts.util.PropertyMessageResources )request
.getAttribute("org.apache.struts.action.MESSAGE")).getMessage("error.productID.blank",null));
%>
【第4步】建立Java屬性檔案
Java屬性檔案相當于資源檔案,以key = value形式儲存了在程式中需要的字元串資訊。Java屬性檔案的擴充名為properties。在<samples工程目錄>"src目錄中建立一個struts目錄,在struts目錄中建立一個ErrorDescription.properties檔案,并輸入如下的内容:
ErrorDescription.properties
error.user.blank = User can't be null.
error.password.blank = Password can't be null.
error.password1.confirmation = Password doesn't match confirmation.
error.email.blank = Email can't be null.
error.email.invalid = It is not a valid email address.
【第5步】配置struts-config.xml檔案
在本例中需要配置struts-config.xml檔案的三個标簽:<form-bean>、<action>和<message-resources>。
1. 配置<form-bean>标簽
這個标簽用來定義ActionForm。在<form-beans>标簽中加入如下所示的<form-bean>标簽:
<form-bean name="simpleValidationForm" type="actionform.SimpleValidationForm" />
2. 配置<action>标簽
這個标簽用來定義Struts中的動作類。在<action-mappings>标簽中加入如下所示的<action>标簽:
<action name="simpleValidationForm" path="/simpleValidation" scope="request" type="action.SimpleValidationAction"
input="simpleValidation.jsp">
<forward name="simple" path="simpleValidation.jsp" />
</action>
<action>标簽中的屬性含義描述如下:
1.
name:表示ActionForm的名稱。也就是<form-bean>标簽中的name屬性的值。
2. path:表示Struts動作,必須以“/”開頭。
3. scope:表示ActionForm類的對象執行個體(在本例中是SimpleValidationForm類的對
象執行個體)儲存的範圍。這個屬性值隻能取request和session。預設值是session。如果scope的值為request,表示将SimpleValidationForm類的對象執行個體以simpleValidationForm作為鍵值儲存到了request的屬性中。如果scope的值為session,表示不将SimpleValidationForm類的對象執行個體儲存到request的屬性中。但不管scope的值是request還是session。Struts都會将SimpleValidationForm類的對象執行個體儲存到session的屬性中。
4. type:表示SimpleValidationAction類的全名。
5. input:表示如果用戶端送出的資料未通過簡單驗證後要跳轉到的頁面,也就是在
SimpleValidationForm類的validate方法中傳回的ActionErrors對象中含有錯誤描述資訊。Struts會自動跳轉到input屬性所指的JSP頁面。
<action>标簽中的子标簽<forward>定義了可以在動作類(在本例中就是SimpleValidationAction類)中讀取的forward頁的URL。
配置<message-resources>标簽
這個标簽用來定義程式中所使用的屬性檔案。在struts-config.xml檔案的<struts-config>根節點中加入如下内容:
<message-resources parameter="struts.ErrorDescription" />
其中parameter屬性表示屬性檔案的路徑,在本例中屬性檔案ErrorDescription.properties位于struts目錄中,是以,parameter屬性的值為struts.ErrorDescription。擴充名properties不用寫。其中“.”也可以使用“/”或“"”代替。
下面我們測試一下這個例子程式。首先啟動Tomcat,然後在IE中輸入如下的URL:
通路上面的URL後的界面如圖1所示。
圖1
在不輸入任何資訊的情況下,點選“确定”按鈕後的界面如圖2所示。
圖2