struts2(七)输入校验
2016-05-08 16:30
585 查看
输入校验简述
由于Web应用的开放性,网络上所有浏览者都能够自由地使用该应用,这样该应用通过输入页面收集的数据可能很复杂,不仅会包含正常用户的误输入,还可能包含恶意用户的恶意输入。因此应用系统需要将这些非法输入阻止在应用之外。
异常输入,可能导致系统非正常中断,严重者会导致系统崩溃。应用程序需要正常处理表现层接受的各种数据,通常的做法是遇到异常输入时应用程序直接返回,提示浏览者必须重新输入,也就是将那些异常输入过滤掉。绝对异常输入的过滤,就是输入校验,也称为数据校验。
输入校验分为客户端校验和服务器端校验,客户端检验主要是过滤正常用户的误操作,主要通过JavaScript代码完成;服务器端校验是整个应用阻止非法数据的最后防线,主要通过在应用中编程实现。
客户端检验的主要作用是防止正常浏览者的误输入,仅能对输入进行初步过滤;对恶意用户的恶意行为,客户端将无能为力。因此,客户端校验绝不可替代服务器端校验。客户端校验也绝不可少,因为Web应用大部分浏览者都是正常的浏览者,他们的输入可能包含大量的误输入,客户端检验把这些误输入阻止在客户端,从而降低了服务器的负载。struts2提供的输入校验功能既包括服务器端校验,也包括客户端校验。
编写校验规则文件
服务端校验是在数据提交到服务器上之后,在Action处理之前,对客户但提交的数据进行校验 。
struts2提供了基于验证框架的输入校验,Struts2校验框架的配置上可以分为:Java Annotation配置和XML配置文件配置。
Java Annotation配置是指,使用Java Annotation语法,在Java源代码上标记需要校验的内容,和校验的方式。
XML配置文件配置是指,使用XML配置文件配置需要校验的内容和校验方式,在这种校验方式下,所有的输入校验只需要编写简单的配置文件,struts2的验证框架将会负责进行服务端校验和客户端校验。
使用struts2的校验框架进行校验无需对程序代码进行修改,只需编写校验规则文件即可,校验规则文件指定每个表单域应该满足怎样的规则。
先写一段表单代码。
这里定义了4个表单域,分别对应name、pass、age、birth等4个请求参数。我们规定如下规则:
>name和pass只能是字母和数字,且长度必须在4到25之间。
>年龄必须是1到150之间的整数。
>生日必须在1900-01-01和2050-02-21之间
下面是该请求对应的Action代码。
代码中的Action提供了4个成员变量封装4个请求参数并提供相应的setter和getter方法。该Action继承了ActionSupport类,因此包含了一个execute方法,且该方法直接返回success字符串,此Action不具备任何输入校验功能。
我们通过为该Action指定一个校验规则文件,来利用struts2的输入校验功能对该Action进行校验。下面是本应用使用的输入校验文件RegistAction-validation.xml。
校验规则文件的根元素是< validator../>元素可包含多个< field-validator…/>或< validator…/>元素,这两个的区别是< field-validator…/>是字段校验器的配置风格,而< validator…/>是非非字段校验器的配置风格。
struts2中的每个Action都有一个校验文件,因此该文件的文件名遵守一定的规则:
< Action 名字>-validation.xml
前面Action名字部分可改,后面-validation.xml是固定不变的,且该文件应保存在与Action class文件相同的路径下。例如,本应用的Action class文件保存在WEB-INF/classes.com.afy/app/action路径下,故该校验文件也该保存在该路径下。
与类型转换失败相似,当输入校验失败后,struts2也是自动返回名为“input”的Result,所以需要在struts.xml文件中配置名为“input”Result。下面是本应用的struts.xml文件中Action的配置片段。
这样就为Action对应的各字段添加了校验规则,而且指定了校验失败后会跳转到registForm.jsp后面,接下来可以在regsitForm.jsp页面中添加< s:fielderror>来输出错误提示。
其他部分不用修改,系统会自动加载该文件,当用户提交请求时,struts2的校验框架会根据该文件对用户请求进行校验。
类型转换失败和输入校验失败的提示信息都被封装成FieldError,并被放入Action Context中,而且校验失败时会将返回input逻辑视图名,且都是用< s:fielderror/>标签来输出错误提示信息。如果开始使用struts2的表单标签来生成表单、表单会自动输出错误提示。
struts2执行数据校验的流程图如下。
国际化提示信息
上面的数据校验中,所有的提示信息都是通过硬编码的方式写在配置文件中的,这种方式显然不利于程序国际化。
当查看每个校验文件时,发现每个< field-validator…/>元素都包含了一个必填的< message…/>子元素,这个子元素中的内容就是校验失败后的提示信息。为了国际化该提示信息,为message元素指定key属性,用于指定国际化提示信息对应的key。
上面代码没有之前给出message的内容,而是指定一个key属性,表明当birth字段违反该校验规则时,对应的提示信息是key为birth.range的国际化信息。
本应用的校验文件中指定了许多国际化信息的key,所有需要在国际化资源文件中增加对应的key,即在国际化资源文件中增加Entry(该国家化资源文件也需要用native2ascii处理)。
运行程序,即可看到输入校验的提示信息变为国际化资源文件提供的信息,这就实现了错误提示信息的国际化。
使用客户端校验
在struts2应用中使用客户端校验执行修改两个地方即可:
1. 将输入页面的表单元素改为使用struts2标签来生成表单;
2. 为该< s:form…/>元素增加validate=“true”属性。
修改前面应用的registForm.jsp页面,将页面代码改为如下形式:
只要简单地为struts2的form标签增加validate=“true”,该表单就具备了客户端校验功能。
虽然使用客户端校验,却看不到弹出JavaScript的警告框,这种效果看起来和服务器端校验差不多,但地址栏的地址依然停留在原来页面,并未提交到对应的Action,说明该数据校验过程时客户端校验。
客户端校验依然是基于JavaScript完成的,因为JavaScript脚本本身的限制,有些服务器端校验不能转换成客户端校验,所以不是所有的服务器端都可以转换成客户端校验的。
由于Web应用的开放性,网络上所有浏览者都能够自由地使用该应用,这样该应用通过输入页面收集的数据可能很复杂,不仅会包含正常用户的误输入,还可能包含恶意用户的恶意输入。因此应用系统需要将这些非法输入阻止在应用之外。
异常输入,可能导致系统非正常中断,严重者会导致系统崩溃。应用程序需要正常处理表现层接受的各种数据,通常的做法是遇到异常输入时应用程序直接返回,提示浏览者必须重新输入,也就是将那些异常输入过滤掉。绝对异常输入的过滤,就是输入校验,也称为数据校验。
输入校验分为客户端校验和服务器端校验,客户端检验主要是过滤正常用户的误操作,主要通过JavaScript代码完成;服务器端校验是整个应用阻止非法数据的最后防线,主要通过在应用中编程实现。
客户端检验的主要作用是防止正常浏览者的误输入,仅能对输入进行初步过滤;对恶意用户的恶意行为,客户端将无能为力。因此,客户端校验绝不可替代服务器端校验。客户端校验也绝不可少,因为Web应用大部分浏览者都是正常的浏览者,他们的输入可能包含大量的误输入,客户端检验把这些误输入阻止在客户端,从而降低了服务器的负载。struts2提供的输入校验功能既包括服务器端校验,也包括客户端校验。
编写校验规则文件
服务端校验是在数据提交到服务器上之后,在Action处理之前,对客户但提交的数据进行校验 。
struts2提供了基于验证框架的输入校验,Struts2校验框架的配置上可以分为:Java Annotation配置和XML配置文件配置。
Java Annotation配置是指,使用Java Annotation语法,在Java源代码上标记需要校验的内容,和校验的方式。
XML配置文件配置是指,使用XML配置文件配置需要校验的内容和校验方式,在这种校验方式下,所有的输入校验只需要编写简单的配置文件,struts2的验证框架将会负责进行服务端校验和客户端校验。
使用struts2的校验框架进行校验无需对程序代码进行修改,只需编写校验规则文件即可,校验规则文件指定每个表单域应该满足怎样的规则。
先写一段表单代码。
<s:form action="regist"> <s:textfield name="name" lable="用户名"/> <s:textfield name="pass" lable="密码"/> <s:textfield name="age" lable="年龄"/> <s:textfield name="birth" lable="生日"/> </s:form>
这里定义了4个表单域,分别对应name、pass、age、birth等4个请求参数。我们规定如下规则:
>name和pass只能是字母和数字,且长度必须在4到25之间。
>年龄必须是1到150之间的整数。
>生日必须在1900-01-01和2050-02-21之间
下面是该请求对应的Action代码。
public class RegistAction extends ActionSupport{ //定义4个成员变量封装请求请求参数 private String name; private String pass; private int age; private Date birth; //下面省略对应的setter和getter方法 ....... }
代码中的Action提供了4个成员变量封装4个请求参数并提供相应的setter和getter方法。该Action继承了ActionSupport类,因此包含了一个execute方法,且该方法直接返回success字符串,此Action不具备任何输入校验功能。
我们通过为该Action指定一个校验规则文件,来利用struts2的输入校验功能对该Action进行校验。下面是本应用使用的输入校验文件RegistAction-validation.xml。
<?xml version="1.0" encoding="utf-8"?> <!--指定校验配置文件的DTD信息--> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <!--校验文件的根元素--> <validators> <!--校验Action的name属性--> <field name="name"> <!--指定name属性必须满足必填规则--> <field-validator type="requiredstring"> <param name="trim">true<param> <message>必须输入名字</message> </field-validator> <field-validator type="regex"> <param name="regex"><![CDATA[(\w{4,25})]]></param> <message>您输入的名字只能是字母和数字,且长度必须在4到25之间</message> </field-validator> </field> <!--校验Action的pass属性--> <field name="pass"> <!--指定pass属性必须满足必填规则--> <field-validator type="requiredstring"> <param name="tim">true</param> <message>必须输入密码</message> </filed-validator> <field-validator type="regex"> <param name="regex"><![CDATA[(\w{4,25})]]></param> <message>您输入的密码只能是字母和数字,且长度必须在4到25之间</message> </field-validator> </fiell> <!--指定age属性必须在指定范围内--> <field name="age"> <field-validator type="int"> <param name="min">1</param> <param name="max">150</param> <message>年纪必须在1到150之间</message> </field-validator> </filed> <!--指定birth属性必须在指定范围内--> <field name="birth"> <field-validator type="date"> <!--下面指定日期字符串时,必须使用本Locale的日期格式--> <param name="min">1900-01-01</param> <param name="max">2050-02-21</param> <message>生日必须在${min}到${max}之间</message> </field-validator> </field> </validators>
校验规则文件的根元素是< validator../>元素可包含多个< field-validator…/>或< validator…/>元素,这两个的区别是< field-validator…/>是字段校验器的配置风格,而< validator…/>是非非字段校验器的配置风格。
struts2中的每个Action都有一个校验文件,因此该文件的文件名遵守一定的规则:
< Action 名字>-validation.xml
前面Action名字部分可改,后面-validation.xml是固定不变的,且该文件应保存在与Action class文件相同的路径下。例如,本应用的Action class文件保存在WEB-INF/classes.com.afy/app/action路径下,故该校验文件也该保存在该路径下。
与类型转换失败相似,当输入校验失败后,struts2也是自动返回名为“input”的Result,所以需要在struts.xml文件中配置名为“input”Result。下面是本应用的struts.xml文件中Action的配置片段。
<!--用户注册的Action--> <action name="regist" class="com.afy.app.action.RegisftAction"> <!--类型转换失败、输入校验失败时转入该页面--> <result name="input">WEB-INF/content/registForm.jsp</result> <result>WEB-INF/content/show.jsp</result> </action>
这样就为Action对应的各字段添加了校验规则,而且指定了校验失败后会跳转到registForm.jsp后面,接下来可以在regsitForm.jsp页面中添加< s:fielderror>来输出错误提示。
其他部分不用修改,系统会自动加载该文件,当用户提交请求时,struts2的校验框架会根据该文件对用户请求进行校验。
类型转换失败和输入校验失败的提示信息都被封装成FieldError,并被放入Action Context中,而且校验失败时会将返回input逻辑视图名,且都是用< s:fielderror/>标签来输出错误提示信息。如果开始使用struts2的表单标签来生成表单、表单会自动输出错误提示。
struts2执行数据校验的流程图如下。
国际化提示信息
上面的数据校验中,所有的提示信息都是通过硬编码的方式写在配置文件中的,这种方式显然不利于程序国际化。
当查看每个校验文件时,发现每个< field-validator…/>元素都包含了一个必填的< message…/>子元素,这个子元素中的内容就是校验失败后的提示信息。为了国际化该提示信息,为message元素指定key属性,用于指定国际化提示信息对应的key。
<?xml version="1.0" encoding="utf-8"?> <!--指定校验配置文件的DTD信息--> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <!--校验文件的根元素--> <validators> <!--校验Action的name属性--> <field name="name"> <!--指定name属性必须满足必填规则--> <field-validator type="requiredstring"> <param name="trim">true<param> <message key="name.requried"/> </field-validator> <field-validator type="regex"> <param name="regex"><![CDATA[(\w{4,25})]]></param> <message key="name.reqex"/> </field-validator> </field> <!--校验Action的pass属性--> <field name="pass"> <!--指定pass属性必须满足必填规则--> <field-validator type="requiredstring"> <param name="tim">true</param> <message key="pass.requried"/> </filed-validator> <field-validator type="regex"> <param name="regex"><![CDATA[(\w{4,25})]]></param> <message key="pass.reqex"/> </field-validator> </fiell> <!--指定age属性必须在指定范围内--> <field name="age"> <field-validator type="int"> <param name="min">1</param> <param name="max">150</param> <message key="age.range"/> </field-validator> </filed> <!--指定birth属性必须在指定范围内--> <field name="birth"> <field-validator type="date"> <!--下面指定日期字符串时,必须使用本Locale的日期格式--> <param name="min">1900-01-01</param> <param name="max">2050-02-21</param> <message key="birth.range"/> </field-validator> </field> </validators>
上面代码没有之前给出message的内容,而是指定一个key属性,表明当birth字段违反该校验规则时,对应的提示信息是key为birth.range的国际化信息。
本应用的校验文件中指定了许多国际化信息的key,所有需要在国际化资源文件中增加对应的key,即在国际化资源文件中增加Entry(该国家化资源文件也需要用native2ascii处理)。
#违反用户名必须输入的提示信息 name.requried=您必须输入用户名! #违反用户名必须匹配正则表达式的提示信息 name.regex=您输入的用户名只能是字母和数字,且长度必须在4到25之间! #违反密码必须输入的提示信息 pass.requried=您必须输入密码! #违反密码必须匹配正则表达式的提示信息 pass.regex=您输入的密码只能是字母和数字,且长度必须在4到25之间! #违反年龄必须在指定范围的提示信息 age.range=您的年龄必须在${min}和${max}之间! #违反生日必须在指定范围的提示信息 birth.range=您的生日必须在${min}和${max}之间!
运行程序,即可看到输入校验的提示信息变为国际化资源文件提供的信息,这就实现了错误提示信息的国际化。
使用客户端校验
在struts2应用中使用客户端校验执行修改两个地方即可:
1. 将输入页面的表单元素改为使用struts2标签来生成表单;
2. 为该< s:form…/>元素增加validate=“true”属性。
修改前面应用的registForm.jsp页面,将页面代码改为如下形式:
<h2>请输入您的注册信息</h2> <s:fielderror/> <s:form action="regist" validate="true"> <s:textfield name="name" lable="用户名"/> <s:textfield name="pass" lable="密码"/> <s:textfield name="age" lable="年龄"/> <s:textfield name="birth" lable="生日"/> </s:form>
只要简单地为struts2的form标签增加validate=“true”,该表单就具备了客户端校验功能。
虽然使用客户端校验,却看不到弹出JavaScript的警告框,这种效果看起来和服务器端校验差不多,但地址栏的地址依然停留在原来页面,并未提交到对应的Action,说明该数据校验过程时客户端校验。
客户端校验依然是基于JavaScript完成的,因为JavaScript脚本本身的限制,有些服务器端校验不能转换成客户端校验,所以不是所有的服务器端都可以转换成客户端校验的。
相关文章推荐
- 20145223《Java程序程序设计》实验报告5
- Java之------socket系列(三)
- java集合17--TreeSet源码走读
- java Swing布局管理之BoxLayout布局
- Java业务逻辑结合MySQL实现登录注册(XMPP协议的运用)
- java集合16-HashSet源码走读
- 20145106 《Java程序设计》第10周学习总结
- 4、struts2 文件上传下载
- spring的spring-config中常用的基础知识
- Cent OS JDK8安装
- eclipse自动提示功能没了的解决办法(转载)
- java集合14--Map总结
- Java之------socket系列(二)UDP
- Java-常量与变量
- java中sleep和wait的区别
- Java Web:Struts2+Hibernate
- Java 实现图片等比例缩略图 (Thumbnailator + Jsp+SpringMVC)
- Java之------socket查看指定URL的Web页编辑器及HTML文档
- java--集合框架Treemap的定义与特殊功能实现
- java集合13--WeakHashMap源码详解