08 04Struts 2.x數據驗證

1 數據驗證方法覆寫

在任何的開發情況下,只要是項目編寫,那麼絕對不可避免的就要涉及到數據驗證部分,但是對於數據驗證的部分應該是有兩種形式的:
(1)第一種形式:客戶端驗證,使用JavaScript完成,如果方便一些使用JQuery中的驗證框架完成;
(2)第二種形式:服務器端驗證,在服務器端進行檢查,這樣即便客戶端驗證失效了,那麼數據依然可以保證正確。

如果要想實現一些基礎驗證,只需要覆寫一些方法即可,在ActionSupport類裏面提供有如下一個方法:
(1)public void validate(),這個方法裏面只適合於編寫進行驗證的操作,這個方法會自動進行調用是在執行具體的業務方法之前執行;
(2)保存單個錯誤信息:public void addFieldError(String fieldName, String errorMessage)
(3)取得全部的錯誤信息:public Map<String,List<String>> getFieldErrors()
在調用validate()方法之後,如果發現裏面有內容(Map集合的長度大於0),那麼就認爲會出現錯誤。會跑到跳轉路徑的key爲input路徑進行錯誤顯示。

範例:定義News.java類

@SuppressWarnings("serial")
public class News implements Serializable{

	private Integer nid;
	private String ntitle;
	private String ncontent;
	private Date npubdate;	
}

範例:定義表單

<form action="" method="post">
	新聞ID:&nbsp;<input type="text" name="news.nid" id="nid">
	新聞標題:&nbsp;<input type="text" name="news.ntitle" id="ntitle">
	新聞內容:&nbsp;<input type="text" name="news.ncontent" id="ncontent">
	發佈日期:&nbsp;<input type="text" name="news.npubdate" id="npubdate">
	<input type="submit" value="submit">
	<input type="reset" value="reset">
</form>

範例:定義news_show.jsp頁面,此頁面顯示提交信息(利用標籤完成)

<body>
	<h1><s:property value="news.nid"/></h1>
	<h1><s:property value="news.nname"/></h1>
	<h1><s:property value="news.ncontent"/></h1>
	<h1><s:property value="news.npubdate"/></h1>
</body>

定義NewsAction,而後覆寫好validate()方法。
範例:定義NewsAction,暫時不加入驗證

@SuppressWarnings("serial")
public class NewsAction extends ActionSupport {
	private News news = new News();
	
	public News getNews() {
		return news;
	}
	
	public String insert(){
		System.out.println(this.news);
		return "news.show";
	}
	
	@Override
	public void validate() {
		System.out.println("*****************");
	}
}

現在的Action只是負責信息顯示,而後跳轉到一個指定的路徑上,而這個路徑要配置的是news_show.jsp頁面。
範例:修改struts.xml文件

<package name="root" namespace="/" extends="struts-default">
	<action name="NewsAction" class="org.lks.action.NewsAction">
		<result name="news.show">news_show.jsp</result>
	</action>
</package>

那麼下面的程序就需要針對於錯誤進行驗證,但是非常遺憾的是,這個驗證發生在賦值之後。在validate()方法裏面所能夠驗證的只有null這一個形式的判斷,那麼既然要驗證必然要保存錯誤信息。
範例:定義全局資源文件——Messages.properties

data.null={0}不允許爲空!

範例:定義struts.properties文件

struts.i18n.encoding=UTF-8
struts.locale=zh_CN

struts.custom.i18n.resources=Messages,Pages

範例:編寫驗證

@Override
	public void validate() {
		if(this.news.getNid() == null || "".equals(this.news.getNid())){
			super.addFieldError("news.nid", super.getText("data.null", new String[]{"新聞ID"}));
		}else if(this.news.getNtitle() == null || "".equals(this.news.getNtitle())){
			super.addFieldError("news.ntitle", super.getText("data.null", new String[]{"新聞標題"}));
		}else if(this.news.getNcontent() == null || "".equals(this.news.getNcontent())){
			super.addFieldError("data.null", super.getText("data.null", new String[]{"新聞內容"}));
		}else if(this.news.getNpubdate() == null || "".equals(this.news.getNpubdate())){
			super.addFieldError("data.null", super.getText("data.null", new String[]{"新聞發佈日期"}));
		}
	}

整個的代碼操作之中只是進行了一個功能的填充。但是如果驗證失敗,它會默認找到input對應的路徑,所以需要在配置action的時候找到input的設置。
範例:修改struts.xml文件

<package name="root" namespace="/" extends="struts-default">
	<action name="NewsAction" class="org.lks.action.NewsAction">
		<result name="news.show">news_show.jsp</result>
		<result name="input">news_insert.jsp</result>
	</action>
</package>

此時一個最爲基礎的驗證就算是完成了。

2 錯誤信息顯示

雖然這個時候已經可以成功的進行了錯誤跳轉,但是跳轉之後可能依然沒有人知道出現了哪些錯誤,那麼現在就必須想辦法在頁面中顯示這些錯誤。

首先必須明確的再次提示,在ActionSupport類裏面提供的取得全部錯誤信息的方法:
(1)取得錯誤信息:public Map<String,List<String>> getFieldErrors()
所有的錯誤信息都是以Map集合形式保存的,而Map中的key是表單的參數名稱,但是最麻煩的是後面的value保存的是List集合,如果是List集合,你這裏面就應該想辦法輸出內容。

當驗證失敗之後,所有保存的錯誤信息都會自動的存放在request屬性範圍之內,而千萬要記住,如果出現了錯誤,會跑到input設置的路徑上進行錯誤顯示。
範例:修改驗證方法

@Override
public void validate() {
	if(this.news.getNid() == null || "".equals(this.news.getNid())){
		super.addFieldError("news.nid", super.getText("data.null", new String[]{"新聞ID"}));
	}
	if(this.news.getNtitle() == null || "".equals(this.news.getNtitle())){
		super.addFieldError("news.ntitle", super.getText("data.null", new String[]{"新聞標題"}));
	}
	if(this.news.getNcontent() == null || "".equals(this.news.getNcontent())){
		super.addFieldError("data.null", super.getText("data.null", new String[]{"新聞內容"}));
	}
	if(this.news.getNpubdate() == null || "".equals(this.news.getNpubdate())){
		super.addFieldError("data.null", super.getText("data.null", new String[]{"新聞發佈日期"}));
	}
}

而後在前臺頁面上顯示出相應的錯誤信息。
範例:顯示錯誤信息

<form action="NewsAction!insert.action" method="post">
	新聞ID:&nbsp;<input type="text" name="news.nid" id="nid" value="1001">
	<span>${fieldErrors['news.nid'][0] }</span><br>
	新聞標題:&nbsp;<input type="text" name="news.ntitle" id="ntitle" value="你好">
	<span>${fieldErrors['news.ntitle'][0] }</span><br>
	新聞內容:&nbsp;<input type="text" name="news.ncontent" id="ncontent" value="我不好">
	<span>${fieldErrors['news.ncontent'][0] }</span><br>
	發佈日期:&nbsp;<input type="text" name="news.npubdate" id="npubdate" value="2020-03-02">
	<span>${fieldErrors['news.npubdate'][0] }</span><br>
	<input type="submit" value="submit">
	<input type="reset" value="reset">
</form>

整個的輸入頁面並沒有使用Struts 2.x所提供的開發標籤,都是利用了request屬性範圍得來的。

疑問:怎麼知道Action跳轉回JSP頁面後會自動傳遞一個名稱爲fieldErrors的request屬性呢?
要知道在整個JSP內置對象裏面,有四種屬性範圍,但是千萬要記住,每一個屬性範圍的內置對象裏面都會提供有一個方法:取得所有屬性的名稱:public Enumeration getAttributeNames()

結論:所有的驗證的操作方法都是在賦值完成之後完成的。這種的驗證操作實際上根本就無效,也根本沒有什麼單獨使用的意義,唯一可以使用的意義只有一個:可以利用input跳轉,而後可以將錯誤信息傳遞給request屬性,進行頁面的內容輸出。

但是此驗證是在賦值後進行,所以一旦數據出現了格式的錯誤,那麼根本就無法進行有效驗證,後臺依舊會出現報錯的情況。

總結:
(1)在執行具體的業務操作方法之前,一定會默認調用validate()方法進行檢查;
(2)所有的錯誤信息都保存在了fieldErrors這個Map集合之中,每一個錯誤信息可以使用addFieldError()方法進行添加;
(3)默認情況下所有的驗證都是在數據賦值成功之後使用的,所以如果直接使用都無用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章