struts2.1.6教程八、验证机制
注意:要想实现校验,action必须继承自ActionSupport类。
1.基于手工编码的校验
我们建立struts2validate项目 ,其中reg.jsp页面主要代码如下:
- <body>
- <s:head/>
- <h3>注册页面</h3>
- <s:form method="post" action="reg" >
- <s:bean name="com.asm.AgeAction" id="aa"></s:bean>
- <s:textfield name="user.username" label="用户名"/>
- <s:property value="errors.user.username"/>
- <s:password name="user.password" label="密码"/>
- <s:password name="user.password2" label="确认密码"/>
- <s:select list="#aa.ageMap" name="user.age" label="年龄" headerValue="填写真实年龄" headerKey="0"/>
- <s:reset value="重置" align="left" />
- <s:submit value="注册" align="left"/>
- </s:form>
- </body>
说明:<s:head/>可以用来对验证信息进行一些美化效果处理,另在此页面中我们用到了一个AgeAction用来动态生成“年龄”表单项,在前面的表单标签中已用过类似的做法。AgeAction的代码如下:
- package com.asm;
- public class AgeAction extends ActionSupport {
- private Map<Integer, String> ageMap;
- public AgeAction() {
- ageMap = new HashMap();
- for (int i = 1; i <= 120; i++) {
- ageMap.put(new Integer(i), i + "");
- }
- }
- ...省略ageMap的get/set方法
- }
Reg action的配置如下:
- <package name="validate" extends="struts-default">
- <action name="reg" class="com.asm.RegAndLoginAction" method="reg">
- <result name="success">/regSuc.jsp</result>
- <result name="login">/reg.jsp</result>
- </action>
- </package>
根据配置,我们来看它的对应Action: RegAndLoginAction,代码如下:
- package com.asm;
- public class RegAndLoginAction extends ActionSupport {
- private User user;
- public String reg() throws Exception {
- if (user.getUsername() == null || user.getUsername().equals("")) {
- this.addFieldError("user.username", "用户名不能为空");
- } else if (!Pattern.matches("^[a-zA-Z][a-zA-Z0-9_]{3,14}$", user.getUsername())) {
- this.addFieldError("user.username", "用户名只能是以字母开头,后面可以跟字母、数字或下滑线,长度只能是4-15位");
- } else if (user.getPassword() == null || user.getPassword().equals("")) {
- this.addFieldError("user.password", "密码不能为空");
- } else if (!user.getPassword().equals(user.getPassword2())) {
- this.addFieldError("user.password2", "两次输入的密码不一致,请重新输入");
- } else if (user.getAge() < 16) {
- this.addFieldError("user.age", "未满16岁,不能注册");
- }
- if (this.hasFieldErrors()) {
- return LOGIN;
- }
- System.out.println("reg success....");
- return SUCCESS;
- }
- ...省略user的get/set方法
- }
说明:当reg.jsp提交给此Action对应的reg方法处理时,它会调用addFieldError把错误信息加到FiledError中去,关于这点,我们可以在前台reg.jsp页面中用<s:debug>调试时,可以看到值栈中的此Action对象中的fieldErrors对应着我们添加的错误信息,因此这点也就为我们取出验证信息提供一个参考,即是说我们可以取出此验证信息,对它进行美化处理,而不是按struts2默认来显示。 后面,我们接着对登录页面用login方法进行了类似的验证(在此省略),所以此action取名为regAndLoginAction.
补充:当我们把login.jsp页面的验证写完后,可以发现reg和login这两个方法显示相当的繁琐,对此我们可以专门把验证分别放在validateReg和validateLogin方法中去。我们新建一个Action来演示,
新的RegAndLogin2Action主要代码如下:
- package com.asm;
- public class RegAndLogin2Action extends ActionSupport {
- private User user;
- @Override
- public void validate() {
- System.out.println("校验的统一出口,对所有方法进行校验:这里可以放一些公共的验证");
- }
- public void validateReg() {
- ...省略,对reg方法进行验证
- }
- public void validateLogin() {
- ...省略,对login方法进行验证
- }
- public String reg() throws Exception {
- System.out.println("reg success....");
- return SUCCESS;
- }
- public String login() throws Exception {
- System.out.println("login success....");
- return SUCCESS;
- }
- ...省略user的get/set方法
- }
说明:当reg.jsp提交给此Action对应的reg方法处理时,它会首先调用此reg方法专属的验证方法valiadteReg(注意取名规则:validate+方法名<首字母大写>),此方法验证完成后,会调用validate方法,此方法完成后才会调用reg方法。因此一般情况下,我们会把一些公共的验证放在validate方法中,而这些所有的验证方法也只进行验证处理,并把错误信息封装到fieldError字段中(或者其它字段)。reg这些真正执行的方法只进行一些其它处理(比如把注册信息写进数据库)。测试时需要修改把前面的配置注释掉,写上下面的配置:
- <action name="login" class="com.asm.RegAndLogin2Action" method="login">
- <result name="success">/logSuc.jsp</result>
- <result name="input">/login.jsp</result>
- </action>
- <action name="reg" class="com.asm.RegAndLogin2Action" method="reg">
- <result name="success">/regSuc.jsp</result>
- <result name="input">/reg.jsp</result>
- </action>
说明:配置中有一个input result的配置,因为带有validate的方法进行验证时,如果验证失败,会返回input所对应的result结果集。
简析校验流程:
(1)类型转换器请求参数执行类型转换,并把转换后的值赋给action中属性。
(2)如果在执行类型转换过程中出现异常,系统会将异常信息保存到ActionContext,conversionError拦截器将异常信息添加到fieldErrors里,不管类型转换是否出现异常都会进入第(3)步。
(3)系统通过反射技术调用action中的validateXxx()方法
(4)再调用action中的validate()方法
(5)经过上面4步,如果系统中的fieldErrors存在错误信息(即存放错误信息的集合size大于0),系统自动将请求转发至名为input的视图。如果系统中的fieldErrors没有任何错误信息,系统将执行action中的处理方法。
注意:经过以上过程的分析,可以知道如果类型转换失败,也会到input视图。
2.基于XML配置形式的校验
新建struts2validateXML项目,在此项目中,基本的代码和上面的struts2validate项目相似,只是在上一个项目中我们在Action的具体方法中进行了验证处理,现在先修改RegAndLoginAction的代码如下:
- package com.asm;
- public class RegAndLoginAction extends ActionSupport {
- private User user;
- public String reg() throws Exception {
- System.out.println("reg success....");
- return SUCCESS;
- }
- public String login() throws Exception {
- System.out.println("login success....");
- return SUCCESS;
- }
- ...省略user的get/set方法
- }
下面我们在action所在的包下建立一个对此Action进行校验的xml文件,文件名为:RegAndLoginAction-validation.xml,取名原则就是actionClassName-validation.xml 。它会对此Action中的所有方法进行校验。主要代码如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE validators PUBLIC
- "-//OpenSymphony Group//XWork Validator 1.0.3//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
- <validators>
- <field name="user.username">
- <field-validator type="requiredstring">
- <message>用户名不能为空</message>
- </field-validator>
- <field-validator type="regex">
- <param name="expression">^[a-zA-Z][a-zA-Z0-9_]{3,14}$</param>
- <message>
- 用户名只能是以字母开头,后面可以跟字母、数字或下滑线,长度只能是4-15位
- </message>
- </field-validator>
- </field>
- <field name="user.password">
- <field-validator type="requiredstring">
- <message>密码不能为空</message>
- </field-validator>
- </field>
- </validators>
进行此配置,相当于在RegAndLoginAciton中增加用validate ()方法进行验证。如果我们想对某个方法进行验证,配置文件应取名为actionClassName-ActionName-validation.xml,比如我们对reg方法进行验证,在前面用到validateReg方法,这里只需增加RegAndLoginAction-reg-validation.xml配置文件即可,它的作用和validateReg方法相同,在此省略此配置文件内容。
关于验证的配置文件中用到的验证类型可以参看文档或者叁看压缩包中的配置参照文件,下面对校验器类型进行简单说明:
Required-必须校验器:要求field的值不能为null
Requiredstring-必须字串校验器:不能为null,用长度大于0,默认情况下会对字串去前后空格
int、[long、short、double]:整数值[long型、短整形、double型]型值必须在指定范围。参数min指定最小值,参数max指定最大值
date-日期校验器:日期校验类型,符合日期格式,用可以使用min/max来指定日期范围
expression-OGNL表达式校验器:expression参数指定ognl表达式,该逻辑表达式基于值栈进行求值,返回true时校验通过,否则不通过,该校验器不可用在字段校验器风格的配置中
fieldexpression-字段ognl表达式校验器:要求field满足一个ognl表达式,expression参数指定ognl表达式,该逻辑表达式基于值栈进行求值,返回true校验通过,否则不通过
email-邮件地址校验器:非空用为合法的邮件地址
url-网址校验器:非空用为合法的url地址
visitor-复合属性校验器:它指定一个校验文件用于校验复合属性中的属性
conversion-转换校验器:指定在类型转换失败时,提示的错误信息
stringlength-字符器长度校验器:要求字段必须在指定的范围内,否则校验失败。minLength参数指定最小长度,maxLength参数指定最大长度。Trim参数指定校验field之前是否去除字串前后的空格
regex-正则表达式校验器:校验字段是否与expression参数指定的正则表达式匹配。caseSensitive参数指定进行匹配时是否区分大小写,默认为true,即区分大小写。
补充:基于xml校验的一些特点
当为某个Action提供了ActionClassName-validation.xml和ActionClassName-ActionName-validation.xml两种规则的校验文件时,系统会按下面的顺序寻找校验文件:(1)ActionClassName-validation.xml
(2)ActionClassName-ActionName-validation.xml
系统寻找到第一个校验文件时还会继续搜索后面的校验文件,当探索到所有校验文件时,会把校验文件里的所有校验规则汇总,然后全部应用于action方法的校验。如果两个校验文件中指定的校验规则冲突,则会只使用后面文件中的校验规则。
当action继承了另一个action,父类action的校验文件会先被搜索到。
假定UserAction继承BaseAction:
<action name="user" class="com.asm.UserAction"
method="execute">访问上面的action,系统会先搜索父类的校验文件:BaseAction-validation.xml,BaseAction-user-validation.xml,接着搜索子类的校验文件:UserAction-validation.xml,UserAction-user-validation.xml.应用于上面action校验规则为四个文件的总和。
struts2.1.6教程八、验证机制的更多相关文章
- struts2官方 中文教程 系列十一:使用XML进行表单验证
在本教程中,我们将讨论如何使用Struts 2的XML验证方法来验证表单字段中用户的输入.在前面的教程中,我们讨论了在Action类中使用validate方法验证用户的输入.使用单独的XML验证文件让 ...
- struts2官方 中文教程 系列八:异常处理
在本教程中,我们将探讨如何启用Struts 2框架处理web应用程序生成的任何未捕获的异常.Struts 2提供了健壮的异常处理,包括能够自动记录任何未捕获的异常,并将用户重定向到错误web页面. 贴 ...
- struts2官方 中文教程 系列六:表单验证
先贴个本帖的地址,以免被爬:struts2教程 官方系列六:表单验证 即 http://www.cnblogs.com/linghaoxinpian/p/6906720.html 下载本章节代码 介 ...
- Struts2数据验证机制
1. 手动验证的实现 只需要在继承ActionSupport类的情况下,直接重写validate()方法即可.使用validate()方法可以对用户请求的多个Action方法进行验证,但其验证的逻辑是 ...
- Laravel教程 八:queryScope 和 setAttribute
Laravel教程 八:queryScope 和 setAttribute 此文章为原创文章,未经同意,禁止转载. Laravel Eloquent Database 直接就是按照上一节所说的那样,我 ...
- Google 推出全新的两步验证机制
近日 Google 在官方的 Apps Updates 博客公布了全新的两步验证功能--Google 提示,新的功能通过与 Google App 联动,进一步将验证确认工作缩减到仅有两步,同时支持 A ...
- struts2官方 中文教程 系列十:Form标签
介绍 在本教程中,我们将探索其他Struts 2表单控件.在前面的教程中,我们介绍了如何使用Struts 2表单(处理表单.表单验证和消息资源文件),我们介绍了如何使用Struts 2 head, f ...
- 逆向工程第004篇:跨越CM4验证机制的鸿沟(中)
一.前言 在上一篇文章的最后,我已经找出了关键的CALL语句,那么这篇文章我就带领大家来一步一步地分析这个CALL.我会将我的思路完整地展现给大家,因此分析过程可能略显冗长,我会分为两篇文章进行讨论. ...
- CRL快速开发框架系列教程八(使用CRL.Package)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
随机推荐
- 由if-else,switch代替方案引起的思考
关键词:条件判断,多态,策略模式,哈希表,字典map 笔者在用python实现事件驱动后,发现python是没有提供switch语句,python官方推荐多用字典来代替switch来实现,这让我就觉得 ...
- STM32学习笔记(二)——串口控制LED
开发板芯片:STM32F407ZGT6 PA9-USART1_TX,PA10-USART1_RX; PF9-LED0,PF10-LED1; 一.串口1配置过程(不使用串口中断): 1.使能时钟,包括G ...
- [洛谷P2580]于是他错误的点名开始了
洛谷P2580的一个水题,用啥都能过,不过为了练习一下刚刚学会的字典树,还是认真做一下吧. #include <cstdio> #include <cstring> using ...
- USACO Section 1.1-3 Friday the Thirteenth
Friday the Thirteenth 黑色星期五 13号又是一个星期五.13号在星期五比在其他日子少吗?为了回答这个问题,写一个程序,要求计算每个月的十三号落在周一到周日的次数. 给出N年的一个 ...
- 实时监听input标签输入 实时监听文本框输入 避免中文输入法无法触发onkeyup事件的问题
前言: 对于实时监听输入,这种需求大多数都是用于一个联想字提醒,智能提醒.大家都知道onkeydown,onkeypress,onkeyup的在监听中文输入法或者右键粘贴的时候都存在一些弊端,不是那么 ...
- 对java面向对象的初识
我其实一直想写点东西练练自己文笔,今天写下这篇技术类型的文章也没有一个好的格式和章法,但万事开头难,那么就从面向对象开始. 我们大部分人都知道互联网软件的存在,时刻影响了我们的现实生活,那么面向对象的 ...
- React-Native 之 redux 与 react-redux
前言 本文 有配套视频,可以酌情观看. 文中内容因各人理解不同,可能会有所偏差,欢迎朋友们联系我讨论. 文中所有内容仅供学习交流之用,不可用于商业用途,如因此引起的相关法律法规责任,与我无关,如文中内 ...
- PPT素才搜索简谈
PPT已经是大部分公司工作汇报.培训.年度总结等不可缺少的办公软件.下面介绍一些关于PPT素才搜索的方法. 第一:模板 1.搜索大法--filetype:对应的文档格式 在关键词后添加这样一段文 ...
- 纯JS单页面赛车游戏代码分享
分享一个以前写的小游戏,纯js游戏,代码很简单.欢迎大家来喷呦! 效果图: 代码展示://直接复制到html文件即可 支持IE9+版本 <!DOCTYPE html> <html&g ...
- 看我如何从一个APK到最终拿下域管理权限
本文我将向大家介绍在企业网络中使用个人智能手机,会给我们企业网络造成怎样的潜在威胁?事实证明,想要欺骗一位企业内部的员工并让其安装恶意应用程序,其实并不困难.一旦成功,攻击者就可以突破企业内网的防护机 ...