国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

Struts2-13 輸入驗證

2019-11-08 03:13:24
字體:
來源:轉載
供稿:網友

  一個健壯的WEB應用程序必須確保用戶的輸入是合法有效的;Struts2即提供了一些基于XWork Validation Framework的內建驗證程序,使得輸入驗證不需要編程,直接在xml配置文件中聲明(待驗證字段、驗證規(guī)則、驗證出錯消息)即可。      Struts2提供聲明式驗證和編程式驗證兩種方式,常采用聲明式驗證程序,其主要需要聲明如下內容:

對哪個Action類或Model類對象的哪個字段進行驗證;采用哪種驗證規(guī)則進行驗證;若驗證失敗,則轉向何處、顯示什么錯誤信息。

一、Struts2內建驗證程序

required:驗證某給定字段的值不是空值null;requiredstring: 驗證某給定字段的值既不是空值 null,也不是空白(trim參數默認為true,可以在驗證前先剔除前后空格);stringlength:驗證一個非空的字段值是不是有足夠的長度;date:驗證某給定日期字段的值是否落在一個給定的范圍內;email:驗證某給定字符串是否是一個合法的E-mail地址;url:驗證某給定字符串是否是一個合法的url;regex:驗證某給定字段的值是否與一個給定的正則表達式模式相匹配(exPResssion、caseSensitive、trim);int:驗證某給定整數字段值是否在某一個范圍內;conversion:驗證對給定Action屬性進行類型轉換是否會出錯,其可以在默認類型轉換消息基礎上添加一條自定義的消息;expression:驗證某給定字段是否滿足一個OGNL表達式,其是非字段驗證程序,驗證失敗時將生成action錯誤(expression參數指用來驗證的OGNL表達式);fieldexpression:驗證某給定字段是否滿足一個OGNL表達式,其是字段驗證程序,驗證失敗時將生成字段錯誤(expression參數指用來驗證的OGNL表達式);

二、聲明式驗證

  聲明式驗證程序分為字段驗證和非字段驗證兩類,字段驗證主要判斷某字段屬性的輸入是否有效,而非字段驗證主要是針對多個字段輸入值之間的邏輯關系進行校驗,如密碼再次輸入確認。

2.1 基于字段的聲明式驗證

(1)基于字段的聲明式驗證程序的具體實現步驟

確定驗證字段:確定哪個Action類或Model類對象的哪個字段需要驗證;編寫驗證程序配置文件:若一個Action類的多個action請求使用相同的驗證規(guī)則,則其文件名為ActionClassName-validation.xml,而不同則為ActionClassName-User_create-validation.xml確定驗證失敗時的響應頁面:在struts.xml文件中定義<result name=“input”> 元素,用于指定轉向頁面。

(2)編寫驗證程序配置文件

將struts-2.3.15.3/apps/struts2-blank/WEB-INF/classes/example下的Login-validation.xml文件復制到當前Action類文件所在路徑下;修改配置文件名為ActionClassName-validation.xml;編寫驗證規(guī)則: 參見struts-2.3.15.3/docs/WW/docs/validation.html文檔即可。<!--驗證程序配置文件核心內容:--><field name="age"> <field-validator type="int"> <param name="min">20</param> <param name="max">50</param> <!--注意:驗證程序錯誤消息可以進行國際化--> <message>Age needs to be between ${min} and ${max}.</message> </field-validator></field>

(3)顯示驗證程序錯誤消息

<!-- 非simple主題自動顯示錯誤消息 --><s:form action="testValidation"> <s:textfield name="age" label="Age"></s:textfield> <s:submit></s:submit></s:form><br><hr><br><!-- simple主題需要使用s:fielderror標簽或EL貨OGNL表達式來顯示錯誤消息 --><s:form action="testValidation2" theme="simple"> Age: <s:textfield name="age" label="Age"></s:textfield> <br> ${fieldErrors.age[0] } <br> <s:fielderror name="age"></s:fielderror> <s:submit></s:submit></s:form>

2.2 聲明式驗證框架的原理

Struts2 默認攔截器棧中提供了validation攔截器,負責加載和執(zhí)行已注冊的驗證程序;每個具體的驗證程序都會對應一個具體的驗證器;配置文件default.xml(位于com.opensymphony.xwork2.validator.validators下)將驗證規(guī)則名稱和驗證器關聯起來,實際驗證的是驗證器。 這里寫圖片描述

2.3 短路驗證

<!-- 設置短路驗證:若當前驗證沒有通過,則不再進行后續(xù)的驗證 --> <field-validator type="conversion" short-circuit="true"> <message>Conversion Error Occurred.</message> </field-validator> <field-validator type="int"> <param name="min">0</param> <param name="max">100</param> <message>Age needs to be between ${min} and ${max}.</message> </field-validator>

  注意:若類型轉換失敗,默認情況下仍會執(zhí)行后續(xù)的輸入驗證攔截器。可通過修改ConversionErrorInterceptor源代碼的方式使 類型轉換失敗時,直接返回input的result,即不再執(zhí)行后續(xù)的驗證攔截器。

// 創(chuàng)建相同的包 -> 新建相同的類 -> 復制源代碼 -> 修改即可Object action = invocation.getAction(); if (action instanceof ValidationAware) { ValidationAware va = (ValidationAware) action; if(va.hasFieldErrors() || va.hasActionErrors()) { return "input"; } }

2.4 非字段驗證

  非字段驗證不是針對單一字段的驗證,可以通過<s:actionerror/>標簽顯示錯誤消息;非字段驗證的配置實例如下:

<!--非字段驗證的配置:實現密碼再次確認的功能--><validators> <validator type="expression"> <param name="expression"><![CDATA[passWord1==password2]]></param> <message>password1 != password2</message> </validator></validators>

2.5 字段驗證 VS 非字段驗證

字段驗證:字段優(yōu)先,可以為一個字段配置多個驗證規(guī)則;非字段驗證:驗證規(guī)則優(yōu)先;大部分驗證規(guī)則支持兩種驗證器,但個別的驗證規(guī)則只能使用非字段驗證,例如表達式驗證。

2.6 錯誤消息的重用性

  問題:多個字段使用同樣的驗證規(guī)則,可否使用同一條驗證消息 ?   解決:利用國際化資源配置文件和fieldName特殊屬性結合來實現,英文資源文件內容如下所示:

error.int=${getText(fieldName)} needs to be between ${min} and ${max}age=Agecount=Count

三、自定義驗證器

3.1 自定義驗證器類

自定義驗證器類需要實現Validator接口,可選擇繼承ValidatorSupport或 FieldValidatorSupport類;自定義一般驗證器類可繼承ValidatorSupport,自定義字段驗證器類可繼承FieldValidatorSupport類;具體實現可以參考目前已經有的驗證器,若驗證程序需要接受輸入參數,則需要為該參數增加對應的屬性和setter()方法。

3.2 配置自定義驗證器

默認情況下, Struts2會在類路徑的根目錄下加載validators.xml文件,在該文件中加載驗證器;若加載失敗,則從com.opensymphony.xwork2.validator.validators下default.xml中加載驗證器;自定義驗證器配置同默認配置文件,配置完畢即可使用。

3.3 自定義18位身份證驗證器

  具體代碼見附錄所示。


四、編碼式驗證

  Struts2提供Validateable接口,可以使Action類實現該接口以提供編程驗證功能,常選擇繼承于實現了Validateable 接口的ActionSupport 類。

@Overridepublic void validate() { if(name == null || name.trim().equals("")) { addFieldError("name", getText("name.null")); }}

附錄:核心程序代碼

這里寫圖片描述

IDCard.java

package com.qiaobc.struts.action;public class IDCard { final int[] wi = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 }; final int[] vi = { 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 }; private int[] ai = new int[18]; public IDCard() {} public boolean Verify(String idcard) { if (idcard.length() == 15) { idcard = uptoeighteen(idcard); } if (idcard.length() != 18) { return false; } String verify = idcard.substring(17, 18); if (verify.equals(getVerify(idcard))) { return true; } return false; } public String getVerify(String eightcardid) { int remaining = 0; if (eightcardid.length() == 18) { eightcardid = eightcardid.substring(0, 17); } if (eightcardid.length() == 17) { int sum = 0; for (int i = 0; i < 17; i++) { String k = eightcardid.substring(i, i + 1); ai[i] = Integer.parseInt(k); } for (int i = 0; i < 17; i++) { sum = sum + wi[i] * ai[i]; } remaining = sum % 11; } return remaining == 2 ? "X" : String.valueOf(vi[remaining]); } public String uptoeighteen(String fifteencardid) { String eightcardid = fifteencardid.substring(0, 6); eightcardid = eightcardid + "19"; eightcardid = eightcardid + fifteencardid.substring(6, 15); eightcardid = eightcardid + getVerify(eightcardid); return eightcardid; } public static void main(String[] args) { String idcard1 = "350211197607142059"; String idcard2 = "350211197607442059"; IDCard idcard = new IDCard(); System.out.println(idcard.Verify(idcard1)); System.out.println(idcard.Verify(idcard2)); }}

IDCardValidator.java:

package com.qiaobc.struts.action;import com.opensymphony.xwork2.validator.ValidationException;import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;public class IDCardValidator extends FieldValidatorSupport { @Override public void validate(Object object) throws ValidationException { // 1. 獲取字段名和字段值 String fieldName = getFieldName(); Object value = this.getFieldValue(fieldName, object); // 2. 驗證 IDCard idCard = new IDCard(); boolean result = idCard.Verify((String) value); // 3. 驗證失敗轉向 if(!result) { addFieldError(fieldName, object); } }}

TestValidationAction.java:

package com.qiaobc.struts.action;import com.opensymphony.xwork2.ActionSupport;public class TestValidationAction extends ActionSupport { private static final long serialVersionUID = 1L; private Integer age; private String password1; private String password2; private String idcard; public String getPassword1() { return password1; } public String getIdcard() { return idcard; } public void setIdcard(String idcard) { this.idcard = idcard; } public void setPassword1(String password1) { this.password1 = password1; } public String getPassword2() { return password2; } public void setPassword2(String password2) { this.password2 = password2; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String execute() throws Exception { System.out.println("age:" + age); System.out.println("password1:" + password1); System.out.println("password2:" + password2); return SUCCESS; }}

TestValidationAction-testValidation-validation.xml:

<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd"><validators> <field name="age"> <field-validator type="int"> <param name="min">20</param> <param name="max">50</param> <message>Age needs to be between ${min} and ${max}.</message> </field-validator> <field-validator type="conversion"> <message>Conversion Error Occurred.</message> </field-validator> </field> <field name="idcard"> <field-validator type="idcard"> <message>It's not a ID Card!</message> </field-validator> </field> <validator type="expression"> <param name="expression"><![CDATA[password1==password2]]></param> <message>password1 != password2</message> </validator></validators>

TestValidationAction-testValidation2-validation.xml:

<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd"><validators> <field name="age"> <!-- 設置短路驗證:若當前驗證沒有通過,則不再進行下面的驗證 --> <field-validator type="conversion" short-circuit="true"> <message>Conversion Error Occurred.</message> </field-validator> <field-validator type="int"> <param name="min">0</param> <param name="max">100</param> <message>Age needs to be between ${min} and ${max}.</message> </field-validator> </field></validators>

struts.xml:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"><struts> <!-- 配置全局范圍內的國際化資源文件 --> <constant name="struts.custom.i18n.resources" value="i18n"></constant> <package name="validation" namespace="/" extends="struts-default"> <action name="testValidation" class="com.qiaobc.struts.action.TestValidationAction"> <result>/success.jsp</result> <!-- 配置輸入驗證失敗時的轉向頁面 --> <result name="input">/validation.jsp</result> </action> <action name="testValidation2" class="com.qiaobc.struts.action.TestValidationAction"> <result>/success.jsp</result> <!-- 配置輸入驗證失敗時的轉向頁面 --> <result name="input">/validation.jsp</result> </action> </package></struts>

validators.xml:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator Definition 1.0//EN" "http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd"><validators> <!-- 配置自定義攔截器 --> <validator name="idcard" class="com.qiaobc.struts.action.IDCardValidator"/></validators>

validation.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> <s:debug></s:debug> <!-- 非simple主題自動顯示錯誤消息 --> <s:form action="testValidation"> <s:textfield name="age" label="Age"></s:textfield> <s:password name="password1" label="password1"></s:password> <s:password name="password2" label="password2"></s:password> <s:actionerror/> <s:textfield name="idcard" label="IDCard"></s:textfield> <s:submit></s:submit> </s:form></body></html>

validation2.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> <s:debug></s:debug> <!-- simple主題需要使用s:fielderror標簽或EL貨OGNL表達式來顯示錯誤消息 --> <s:form action="testValidation2" theme="simple"> Age: <s:textfield name="age" label="Age"></s:textfield> <br><br> <s:fielderror name="age"></s:fielderror> <s:submit></s:submit> </s:form></body></html>

ConversionErrorInterceptor.java:

package com.opensymphony.xwork2.interceptor;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.ValidationAware;import com.opensymphony.xwork2.conversion.impl.XWorkConverter;import com.opensymphony.xwork2.util.ValueStack;import org.apache.commons.lang3.StringEscapeUtils;import java.util.HashMap;import java.util.Map;public class ConversionErrorInterceptor extends AbstractInterceptor { public static final String ORIGINAL_PROPERTY_OVERRIDE = "original.property.override"; protected Object getOverrideExpr(ActionInvocation invocation, Object value) { return escape(value); } protected String escape(Object value) { return "/"" + StringEscapeUtils.escapeJava(String.valueOf(value)) + "/""; } @Override public String intercept(ActionInvocation invocation) throws Exception { ActionContext invocationContext = invocation.getInvocationContext(); Map<String, Object> conversionErrors = invocationContext.getConversionErrors(); ValueStack stack = invocationContext.getValueStack(); HashMap<Object, Object> fakie = null; for (Map.Entry<String, Object> entry : conversionErrors.entrySet()) { String propertyName = entry.getKey(); Object value = entry.getValue(); if (shouldAddError(propertyName, value)) { String message = XWorkConverter.getConversionErrorMessage(propertyName, stack); Object action = invocation.getAction(); if (action instanceof ValidationAware) { ValidationAware va = (ValidationAware) action; va.addFieldError(propertyName, message); } if (fakie == null) { fakie = new HashMap<Object, Object>(); } fakie.put(propertyName, getOverrideExpr(invocation, value)); } } if (fakie != null) { // if there were some errors, put the original (fake) values in place right before the result stack.getContext().put(ORIGINAL_PROPERTY_OVERRIDE, fakie); invocation.addPreResultListener(new PreResultListener() { public void beforeResult(ActionInvocation invocation, String resultCode) { Map<Object, Object> fakie = (Map<Object, Object>) invocation.getInvocationContext().get(ORIGINAL_PROPERTY_OVERRIDE); if (fakie != null) { invocation.getStack().setExprOverrides(fakie); } } }); } // 核心代碼 Object action = invocation.getAction(); if (action instanceof ValidationAware) { ValidationAware va = (ValidationAware) action; if(va.hasFieldErrors() || va.hasActionErrors()) { return "input"; } } return invocation.invoke(); } protected boolean shouldAddError(String propertyName, Object value) { return true; }}
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 河池市| 洛隆县| 高邮市| 沂南县| 溧水县| 曲周县| 锡林郭勒盟| 当阳市| 连山| 盐池县| 新野县| 大石桥市| 南宫市| 霸州市| 闽清县| 康定县| 淮南市| 安阳市| 牟定县| 左权县| 万全县| 湄潭县| 龙胜| 新乐市| 康马县| 久治县| 昆明市| 信阳市| 崇文区| 澄城县| 五莲县| 镇雄县| 高青县| 博客| 托克托县| 华安县| 佛坪县| 松桃| 郑州市| 阿鲁科尔沁旗| 英德市|