在上一篇文章中,咱們學習了數據類型轉換,咱們提到了表示層數據處理的兩個方法,也提到了用戶輸入數據須要進行類型轉換才能獲得咱們想要的數據,那麼,咱們怎麼肯定類型轉換後的數據,是咱們想要的數據呢?這裏有點繞。你能夠這樣想:一個成年男子年齡是18歲,你如今想要獲得18這個數據,可是,用戶輸入32,通過類型轉換也是對的,可是數據不是你想要的。這時候,咱們要怎麼辦?因此輸入驗證在這裏就有用處了。html
類型轉換和輸入驗證的關係是:類型轉換是輸入驗證的前提,若是類型轉換都出錯了,那就不用再進行輸入驗證了。可是不少時候類型轉換和輸入驗證是同時完成的。java
輸入驗證有兩種:正則表達式
一、客戶端驗證;apache
二、服務端驗證。這裏主要講解的是服務端驗證(重寫ValidateXxx方法和xml配置文件驗證)安全
一、類型轉換器負責對字符串的請求參數進行類型轉換,並將這些值設置成Action的屬性值服務器
二、在執行類型轉換過程當中可能出現異常,若是出現異常,異常信息會自動保存到ActionContext中,conversionError攔截器負責將其封裝到fieldError中框架
三、經過反射調用ValidateXxx()方法,其中Xxx是即將處理用戶請求的處理邏輯所對應的方法名jsp
四、調用Action類的Validate方法ide
五、若是上面的步驟沒有出現fieldError,將調用Action裏處理用戶請求的處理方法,若是出現fieldError,系統將轉入input邏輯視圖所指定的視圖。post
2.一、輸入驗證這裏講解的有兩種方式:
一、重寫Validate方法或者自定義ValidateXxx方法(其中的Xxx是本身定義的名字,會先執行該方法,在執行Validate方法)
二、新建xml進行驗證
在MVC框架,都會提供規範的數據驗證部分,Struts2在這裏提供的是一個Validate方法,咱們重寫Validate方法就能夠進行輸入驗證,可是,重寫Validate方法有兩個點須要知道:一、Validate方法會在execute方法以前被執行;二、Validate方法對全部的Action都會執行校驗規則,爲了區別某一個Action,咱們可使用ValidateXxx方法。
注意:如下的例子是局部類型轉換和輸入驗證一塊兒使用的例子。
簡單的註冊驗證例子:
新建實體類User:
package com.validatexxx; public class User { private String username; private String password; private String repassword; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRepassword() { return repassword; } public void setRepassword(String repassword) { this.repassword = repassword; } }
新建視圖:Register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>註冊用戶</title> </head> <body> <h2>使用validateXXX()方法驗證</h2> <form action="register_test"> 用戶:<input type="text" name="user"><br/> 密碼:<input type="password" name="user"><br/> 密碼:<input type="password" name="user"><br/> <input type="submit" value="提交"> </form> </body> </html>
新建RegisterAction類繼承ActionSupport
package com.validatexxx; import com.opensymphony.xwork2.ActionSupport; //重寫validate()和validateXXX指定方法進行驗證 /* * 在struts.xml配置method方法爲test(),會先調用ValidateTest()方法, * 而後在調用validate方法 * 以後test方法被調用 * */ public class RegisterAction extends ActionSupport { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } //2 @Override public void validate(){ System.out.println("重寫Validate方法"); if (null == user.getPassword() || "".equals(user.getPassword()) || null == user.getRepassword() || "".equals(user.getRepassword())) { this.addFieldError("repassword", "repassword should be same password"); return; } if (!user.getPassword().equals(user.getRepassword())) { //當FieldError中存在數據時,服務器會自動幫咱們跳轉到input的邏輯視圖 this.addFieldError("repassword", "repassword should be same password"); } } //1 public void validateTest(){ System.out.println("自定義校驗方法:ValidateTest"); } //3 public String test(){ System.out.println("test:方法"); return SUCCESS; } }
注意:這裏的屬性是User,因此你jsp頁面參數的名字要寫實例的名字user,而後你還須要去建立一個類型轉換器,返回一個填充好數據的類
新建struts.xml,存放在WEB-INF/classes/struts.xml
注意:這裏的method必須是你ValudateXxx()方法後面你本身定義的,筆者這裏是test。使用*的話,struts2還必須配置 strict-method-invocation="false",聽說是由於版本過高了,它的安全性增長了,全部必須加纔可以使用*
新建Usertypeconverter類繼承StrutsTypeConverter(建立一個類型轉換器)
package com.validatexxx; import java.util.Map; import org.apache.struts2.util.StrutsTypeConverter; //類型轉換的類 public class Usertypeconverter extends StrutsTypeConverter { @Override public Object convertFromString(Map arg0, String[] arg1, Class arg2) { System.out.println("Usertypeconverter:類型轉換!"); User user = new User(); user.setUsername(arg1[0]); user.setPassword(arg1[1]); user.setRepassword(arg1[2]); return user; } @Override public String convertToString(Map arg0, Object arg1) { User u = (User)arg1; return u.getUsername()+"!"; } }
注意:該類型轉換器建立好以後還需新建一個RegisterAction-conversion.properties,放在同級目錄下
該文件的內容有:
前面是你在RegisterAction的屬性名,後面是類型轉換器的具體路徑。
新建成功視圖:success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Success</title> </head> <body> <h2>服務端使用validate方法驗證</h2> 成功 </body> </html>
新建錯誤視圖:input.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> Error:<s:fielderror/> </body> </html>
代碼執行成功的效果以下:
Register.jsp頁面
成功跳轉的頁面爲:success.jsp
控制檯測試結果爲:
數據跳轉到Usertypeconverter進行類型轉換,以後跳轉到RegisterAction,執行ValidateTest方法(),Validate,test以後返回SUCCESS,而後執行result的視圖。
咱們看代碼執行失敗的順序:
Register.jsp頁面
input.jsp頁面
控制檯測試效果:
在Validate方法裏面,筆者代碼爲:this.addFieldError(),在前面有說過,若是添加錯誤的話,那麼服務器會自動幫咱們跳轉到錯誤的界面。它會返回input,而input在struts.xml中就有配置,會返回到input.jsp界面。
新建視圖界面:Test.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>使用XML校驗</title> </head> <body> <s:form action="empinfo" method="post"> <s:textfield name="name" label="Name" size="20" /> <s:textfield name="age" label="Age" size="20" /> <s:submit name="submit" label="Submit" align="center" /> </s:form> </body> </html>
新建Employee類繼承ActionSupport
該類有使用重寫Validate方法和Xml配置,咱們能夠選擇其中一種進行驗證就能夠
package com.validatexxx; import com.opensymphony.xwork2.ActionSupport; //使用validate()方法驗證,這是服務端驗證! public class Employee extends ActionSupport { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //第二步再執行該方法 public String execute(){ System.out.println("execute:"+this.age); return SUCCESS; } /* 使用服務端的校驗:重寫validate方法(); //第一步先執行該方法 //重寫validate方法有缺陷:每次都會使用validate方法驗證,形成極大的資源浪費。 public void validate(){ System.out.println("validate"); if (name == null || name.trim().equals("")) { //當往該方法添加數據的時候,服務器會返回input,以後跳轉到input.jsp頁面中。 addFieldError("name","The name is required"); } if (age < 28 || age > 65) { addFieldError("age","Age must be in between 28 and 65"); } } */ }
在Struts.xml中進行配置:
這裏的success.jsp和input.jsp仍是使用上面的。
以後咱們須要新建Employee-validation.xml,路徑放在與Employee同級目錄下,注意:-validation.xml是固定不變的
內容爲:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <validators> <field name="name"> <field-validator type="required"> <message> The name is required. </message> </field-validator> </field> <field name="age"> <field-validator type="int"> <param name="min">29</param> <param name="max">64</param> <message> Age must be in between 28 and 65 </message> </field-validator> </field> </validators>
重點:該文件的dtd限制必須有,否則回報錯誤:
ERROR DefaultDispatcherErrorHandler Exception occurred during processing request: [Connection timed out: connect - [unknown location], null]
接下來咱們使用http://localhost:8080/LearStruts2/ValidateJSP/Test.jsp進行訪問。
測試成功:
Test.jsp界面:
success.jsp
測試失敗例子:
input.jsp界面:
說明例子是正確的。
其實在Struts2中有多個內置驗證器:必填驗證器,必填字符串驗證器,整數驗證器,日期驗證器,表達式驗證器,字符長度驗證器,正則表達式驗證器...等等,這個有須要的話,筆者在一一述說。
以上就是輸入驗證的兩種方式。不足之處請下方留言,我會改正,謝謝!