概述

一个健壮的 web 应用程序必须确保用户输入是合法、有效的.

Struts2 的输入验证

  –基于 XWork Validation Framework 的声明式验证:Struts2 提供了一些基于 XWork Validation Framework 的内建验证程序. 使用这些验证程序不需要编程, 只要在一个 XML 文件里对验证程序应该如何工作作出声明就可以了. 需要声明的内容包括:

    对哪个 Action 或 Model 的那个字段进行验证

    使用什么验证规则

    在验证失败时应该把什么样的出错消息发送到浏览器端

  –编程验证:通过编写代码来验证用户输入

声明式验证的 helloworld

I.  先明确对哪一个 Action 的哪一个字段进行验证: age

II. 编写配置文件:

  > 把 struts-2.3.15.3\apps\struts2-blank\WEB-INF\classes\example 下的 Login-validation.xml 文件复制到当前 Action 所在的包下.
     > 把该配置文件改为: 把  Login 改为当前 Action 的名字.
     > 编写验证规则: 参见 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>

  > 该错误消息可以国际化吗. 可以   <message key="error.int"></message>.

    再在 国际化资源文件 中加入一个键值对: error.int=^^^Age needs to be between ${min} and ${max}

III. 若验证失败, 则转向 input 的那个 result. 所以需要配置 name=input 的 result

 <result name="input">/validation.jsp</result>

IV. 如何显示错误消息呢 ?

  > 若使用的是非 simple, 则自动显示错误消息.
     > 若使用的是 simple 主题, 则需要 s:fielderror 标签或直接使用 EL 表达式(使用 OGNL)

    ${fieldErrors.age[0] }
OR
<s:fielderror fieldName="age"></s:fielderror>*

若一个 Action 类可以应答多个 action 请求, 多个 action 请求使用不同的验证规则, 怎么办 ?

  > 为每一个不同的 action 请求定义其对应的验证文件: ActionClassName-AliasName-validation.xml

  > 不带别名的配置文件: ActionClassName-validation.xml 中的验证规则依然会发生作用. 可以把各个 action 公有的验证规则配置在其中. 但需要注意的是, 只适用于某一个 action 的请求的验证规则就不要这里再配置了.

Struts2 内建的验证规则

  required: 确保某给定字段的值不是空值 null

  requiredstring: 确保某给定字段的值既不是空值 null, 也不是空白.

    –trim 参数. 默认为 true, 表示 struts 在验证该字段值之前先剔除前后空格.

  stringlength: 验证一个非空的字段值是不是有足够的长度.

    –minLength: 相关字段的最小长度. 若没有给出这个参数, 该字段将没有最小长度限制

    –maxLength:相关字段的最大长度. 若没有给出这个参数, 该字段将没有最大长度限制

    –trim: 在验证之前是否去除前后空格

  date: 确保某给定日期字段的值落在一个给定的范围内

    –max:相关字段的最大值. 若没给出这个参数, 该字段将没有最大值限制

    –min:相关字段的最小值. 若没给出这个参数, 该字段将没有最小值限制

  email: 检查给定 String 值是否是一个合法的 email

  url: 检查给定 String 值是否是一个合法的 url

  regex: 检查某给定字段的值是否与一个给定的正则表达式模式相匹配.

    –expresssion*: 用来匹配的正则表达式

    –caseSensitive: 是否区分字母的大小写. 默认为 true

    –trim: 是否去除前后空格. 默认为 true

  int: 检查给定整数字段值是否在某一个范围内

    –min: 相关字段的最小值. 若没给出这个参数, 该字段将没有最小值限制

    –max: 相关字段的最大值. 若没给出这个参数, 该字段将没有最大值限制

  conversion: 检查对给定 Action 属性进行的类型转换是否会导致一个转换错误. 该验证程序还可以在默认的类型转换消息的基础上添加一条自定义的消息

  expression 和 fieldexpression: 用来验证给定字段是否满足一个 OGNL 表达式.

    –前者是一个非字段验证程序, 后者是一个字段验证程序.

    –前者在验证失败时将生成一个 action 错误, 而后者在验证失败时会生成一个字段错误

    –expression*: 用来进行验证的 OGNL 表达式

声明式验证框架的原理:

  > Struts2 默认的拦截器栈中提供了一个 validation 拦截器

  > 每个具体的验证规则都会对应具体的一个验证器. 有一个配置文件把验证规则名称和验证器关联起来了. 而实际上验证的是那个验证器. 该文件位于 com.opensymphony.xwork2.validator.validators 下的 default.xml

 <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>

短路验证:

若对一个字段使用多个验证器, 默认情况下会执行所有的验证. 若希望前面的验证器验证没有通过, 后面的就不再验证, 可以使用短路验证

        <!-- 设置短路验证: 若当前验证没有通过, 则不再进行下面的验证 -->
<field-validator type="conversion" short-circuit="true">
<message>^Conversion Error Occurred</message>
</field-validator> <field-validator type="int">
<param name="min">20</param>
<param name="max">60</param>
<message key="error.int"></message>
</field-validator>

若类型转换失败, 默认情况下还会执行后面的拦截器, 还会进行 验证. 可以通过修改 ConversionErrorInterceptor 源代码的方式使当类型转换失败时, 不再执行后续的验证拦截器, 而直接返回 input 的 result

        Object action = invocation.getAction();
if (action instanceof ValidationAware) {
ValidationAware va = (ValidationAware) action; if(va.hasFieldErrors() || va.hasActionErrors()){
return "input";
}
}

关于非字段验证: 不是针对于某一个字段的验证.

    <validator type="expression">
<param name="expression"><![CDATA[password==password2]]></param>
<message>Password is not equals to password2</message>
</validator>

  显示非字段验证的错误消息, 使用 s:actionerror 标签:  <s:actionerror/>

不同的字段使用同样的验证规则, 而且使用同样的响应消息 ?

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

age=\u5E74\u9F84
count=\u6570\u91CF

自定义验证器:

I.   定义一个验证器的类

  > 自定义的验证器都需要实现 Validator.
     > 可以选择继承 ValidatorSupport 或 FieldValidatorSupport 类
     > 若希望实现一个一般的验证器, 则可以继承 ValidatorSupport
     > 若希望实现一个字段验证器, 则可以继承 FieldValidatorSupport
    
     > 具体实现可以参考目前已经有的验证器.
    
     > 若验证程序需要接受一个输入参数, 需要为这个参数增加一个相应的属性

II.  在配置文件中配置验证器

  > 默认情况下下, Struts2 会在 类路径的根目录下加载 validators.xml 文件. 在该文件中加载验证器.该文件的定义方式同默认的验证器的那个配置文件: 位于 com.opensymphony.xwork2.validator.validators 下的 default.xml

  > 若类路径下没有指定的验证器, 则从 com.opensymphony.xwork2.validator.validators 下的 default.xml 中的验证器加载

III. 使用: 和目前的验证器一样.

IV. 示例代码: 自定义一个 18 位身份证验证器

 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));
} }

IDCard.java

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);
}
}
}

IDCardValidator

Struts2 的验证的更多相关文章

  1. 【Java EE 学习 35 下】【struts2】【struts2文件上传】【struts2自定义拦截器】【struts2手动验证】

    一.struts2文件上传 1.上传文件的时候要求必须使得表单的enctype属性设置为multipart/form-data,把它的method属性设置为post 2.上传单个文件的时候需要在Act ...

  2. struts2 的验证框架validation如何返回json数据 以方便ajax交互

    struts2 的验证框架validation简单,好用,但是input只能输出到jsp页面通过struts2的标签<s:fielderror  />才能取出,(EL应该也可以). 如果使 ...

  3. Struts2 框架验证

    struts2框架验证(xml方式):    * 首先要从页面中获取对应的标签name属性的值,在动作类action中声明同名的属性,提供get和set方法        * 创建一个xml格式验证文 ...

  4. Struts2数据验证机制

    1. 手动验证的实现 只需要在继承ActionSupport类的情况下,直接重写validate()方法即可.使用validate()方法可以对用户请求的多个Action方法进行验证,但其验证的逻辑是 ...

  5. Struts2数据验证与使用Java代码进行数据验证

    Struts2数据验证 使用Java代码进行数据验证 重写ActionSupport的validate()方法 对Action类的中所有请求处理方法都会进行验证! 对Action类的数据属性进行检查, ...

  6. struts2输入验证

    1.方法     ① 基于Annotations的验证       ②基于XML配置的验证 http://blog.csdn.net/furongkang/article/details/692204 ...

  7. Struts2 权限验证

    之前的Struts2项目通过再Sitemesh的母版页中使用Struts的if标签进行了session判断,使得未登录的用户不能看到页面,但是这 种现仅仅在view层进行,如果未登录用户直接在地址栏输 ...

  8. Struts2 手动验证

    * 首先要从页面中获取对应的标签name属性的值,在动作类action中声明同名的属性,提供get和set方法        * 要继承ActionSupport类或者实现Validateable接口 ...

  9. struts2使用验证文件实现校验

    原创 struts2框架提供了一种基于验证文件的输入验证方式,将验证规则保存在特定的验证文件中. 验证文件的命名规则 一般情况下,验证文件的命名规则是:Action类名-validation.xml. ...

随机推荐

  1. DOM加载:浏览器渲染和操作顺序(转载 学习中。。。)

    DOM加载:浏览器渲染和操作顺序 1.HTML解析完毕 2.外部脚本和样式表加载完毕 3.脚本在文档内解析并执行 4.HTML DOM完全构造起来 5.图片和外部内容加载 6.网页完成加载 基于这个顺 ...

  2. Android 数据库升级解决方案

    转自:http://blog.csdn.net/leehong2005/article/details/9128501 请考虑如下情况: 在数据库升级时,不同版本的数据库,他们定义的表结构完全可能是不 ...

  3. Spring 定时任务的配置

    1.applicationContext.xml 中 加入task 的声明与xsd ? 1 xmlns:task="http://www.springframework.org/schema ...

  4. Android_SDK的常用命令

    一.配置环境变量 要想使用这些命令,就必须先配置环境变量.  将android-sdk-windows目录下的platform-tools目录和tools目录配置到path环境变量中 二.adb命令 ...

  5. MySQL在windows系统中修改datadir路径后无法启动问题,报错1067

    windows server2008下如何更改MySQL数据库的目录的帖子已经很多了,这里简单介绍一个步骤,如果不成功请先查看其它帖子. 更改默认的mysql数据库目录 将 C:\Documents ...

  6. HTML JSP Servlet 的 相对路径 绝对路径

    HTML 相对路径 - 没有最前面的 /: 相对于当前文件,和OS一样 绝对路径 - 前面带 / : 相对于  http://<host>:port/ Servlet 相对路径 - 相对于 ...

  7. 转!!java中关键字volatile的作用

    用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来 ...

  8. Machine Learning - 第4周(Neural Networks: Representation)

    Neural networks is a model inspired by how the brain works. It is widely used today in many applicat ...

  9. 使用TCP/IP的套接字(Socket)进行通信

    http://www.cnblogs.com/mengdd/archive/2013/03/10/2952616.html 使用TCP/IP的套接字(Socket)进行通信 套接字Socket的引入 ...

  10. openmpi出现Segmentation Fault而终止运算

    欢迎关注我的社交账号: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://gith ...