自定义验证器——用Struts2框架以框架师的思维灵活做好该事情

面对的问题:自定义一个18位身份验证器,编写验证器,在validators.xml文件中进行注册、在验证配置文件中使用?

第一部分:理解Struts2中自带的验证器

第二部分:怎样通过服务器(后台),再次对前台的数据进行验证

第三部分:用Struts2来自定义验证器(问题解决方案)

第一部分:理解Struts2中自带的验证器

Struts2框架中自带的后台服务器验证分为两种:声明式验证编程式验证

u  声明式验证(重点)

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

?  使用什么验证规则

?  如果验证失败, 转向哪一个页面, 显示是什么错误消息

u  编程式验证

声明式验证(重点)详细分析:

1、先明确对哪一个 Action 的哪一个字段进行验证: 比如说“age”字段。

2、编写配置文件:

>把 struts-2.3.15.3\apps\struts2-blank \WEB-INF\src\java\example 下的 Login-validation.xml 文件复制到当前 Action 所在的包下。

>把该配置文件改为: 把Login 改为当前 Action 的名字,比如本例用的到,如下文件.


E:\Java开发的工具包\struts2.X 开源工具包\struts-2.3.15.1\apps\struts2-blank\WEB-INF\src\java\example详细信息


<!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="username">

<field-validator
type="requiredstring">

<message
key="requiredstring"/>

</field-validator>

</field>

<field
name="password">

<field-validator
type="requiredstring">

<message
key="requiredstring"/>

</field-validator>

</field>

</validators>

>编写验证规则: 参见 struts-2.3.15.3/docs/WW/docs/validation.html文档即可(帮助文档——很实用的文档).


1.    conversion validator

2.    date
validator

3.    double validator

4.    email validator

5.    expression validator

6.    fieldexpression validator

7.    int validator

8.    regex validator

9.    required validator

10.  requiredstring validator

11.  short validator

12.  stringlength validator

13.  url validator

14.  visitor validator

15.  conditionalvisitor validator

单击date validator进入相应的页面——如下图所示:

拷贝相应的文件进行TestValidationAction-validation.xml配置文件中

> 在配置文件中可以定义错误消息:

<fieldname="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>

> 该错误消息也可以国际化操作,详细请参看以前写的blog《用Struts2进行中英文一键切换——包含详细的源代码解析及Struts2国际化原理的理解》


在TestValidationAction-validation.xml文件中添加如下信息


<field-validator
type="int">

<param
name="min">20</param>

<param
name="max">60</param>

<message
key="error.int"></message>

</field-validator>

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

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


在src/struts.xml文件中添加如下信息:


<action
name="testValidation"
class="com.atguigu.struts2.validation.app.TestValidationAction">

<result>/success.jsp</result>

<!-- 若验证失败转向的 input -->

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

</action>


com.atguigu.struts2.validation.app.TestValidationAction的内容


4、如何显示错误消息呢 ?

u  若使用的是非 simple(主要是指Struts2中JSP页面《展现出》中主题的设置,一般默认的为XHTML主题,该文件在源代码中的位置为:
\WebContent\WEB-INF\lib\struts2-core-2.3.15.3.jar\template.simple), 则自动显示错误消息。

u  若使用的是simple主题, 则需要 s:fielderror 标签或直接使用 EL 表达式(使用 OGNL)


<!-- 要求年龄必须在 20-50
之间 -->

<s:form
action="testValidation"
theme="simple">

Age: <s:textfield
name="age"
label="Age"></s:textfield>

<%--

${fieldErrors.age[0] }

--%>

<s:fielderror
fieldName="age"></s:fielderror>

<s:submit></s:submit>

</s:form>

5、关键点理解:若一个 Action 类可以应答多个 action 请求, 多个 action 请求使用不同的验证规则, 怎么办 ?

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

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

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


<!-- 针对 age
属性进行验证.
基于字段的验证 -->

<field
name="age">

<!-- 设置短路验证:
若当前验证没有通过,
则不再进行下面的验证 -->

<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>

</field>

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


具体步骤如下:

1、 通过Struts-default.xml文件中找到conversionError拦截器,查看相应的信息,如下所示:<interceptor
name="conversionError"
class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>

2、 通过Ctrl + Shift + T,输入StrutsConversionErrorInterceptor追踪到该方法。之后追踪到该方法的父类ConversionErrorInterceptor。

3、 在自己创建的项目src先创建com.opensymphony.xwork2.interceptor包,之后创建ConversionErrorInterceptor.java的Java类。

4、 将追踪到的com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.java源代码拷贝到刚好创建的文件中。之后再添加如下语句。

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


(src\com.atguigu.struts2.validation.app)


<!-- 测试非字段验证 -->

<validator
type="expression">

<param
name="expression"><![CDATA[password==password2]]></param>

<message>Password is not equals to password2</message>

</validator>


(WebContent\validation.jsp)


Password: <s:password
name="password"></s:password>

Password2: <s:password
name="password2"></s:password>


( src\com\atguigu\struts2\validation\app\TestValidationAction.java)

在该方法中添加password和password2两个属性,及相应的get和set方法。


public
class
TestValidationAction extends ActionSupport{

private String
password;

private String
password2;

public String getPassword() {

return
password;

}

public
void
setPassword(String password) {

this.password = password;

}

public String getPassword2() {

return
password2;

}

public
void
setPassword2(String password2) {

this.password2 = password2;

}

}

细节注意:显示非字段验证的错误消息, 使用 s:actionerror 标签:  (单独一行就行了)<s:actionerror/>

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

第二部分:怎样通过服务器(后台),再次对前台的数据进行验证

1、声明式验证框架的原理:

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

u  每个具体的验证规则都会对应具体的一个验证器. 有一个配置文件把验证规则名称和验证器关联起来了. 而实际上验证的是那个验证器.

u  该文件位于 com.opensymphony.xwork2.validator.validators下的default.xml



<interceptor
name="timer"
class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>

<interceptor
name="logger"
class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>

<interceptor
name="chain"
class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>

<interceptor
name="staticParams"
class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>

<interceptor
name="params"
class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

<interceptor
name="filterParams"
class="com.opensymphony.xwork2.interceptor.ParameterFilterInterceptor"/>

<interceptor
name="removeParams"
class="com.opensymphony.xwork2.interceptor.ParameterRemoverInterceptor"/>

<interceptor
name="modelDriven"
class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>

<interceptor
name="scopedModelDriven"

class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>

<interceptor
name="validation"
class="com.opensymphony.xwork2.validator.ValidationInterceptor"/>

<interceptor
name="workflow"
class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>

<interceptor
name="prepare"
class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>

<interceptor
name="conversionError"
class="com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor"/>

<interceptor
name="alias"
class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>

<interceptor
name="exception"
class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>

<interceptor
name="i18n"
class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>

第三部分:怎样用Struts2来自定义验证器(详细原理阐述)

I、整个流程步骤简介:

A.   自定义的验证器都需要实现 Validator.(相当于一个JavaBean)

B.   可以选择继承 ValidatorSupport 类或 FieldValidatorSupport 类

C.   若希望实现一个一般的验证器, 则可以继承 ValidatorSupport

D.   若希望实现一个字段验证器, 则可以继承 FieldValidatorSupport

E.   具体实现可以参考目前已经有的验证器(Struts2自带的验证器).

F.   若验证程序需要接受一个输入参数, 需要为这个参数增加一个相应的属性

II、在配置文件中配置验证器(验证配置文件加载顺序):

A.   默认情况下, Struts2 会在 类路径的根目录下加载 validators.xml
文件. 在该文件中加载验证器.


该文件的定义方式同默认的验证器的那个配置文件一样,可以参看其进行书写: 默认文件位于 com.opensymphony.xwork2.validator.validators 下的 xwork-default.xml

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

III. 自定义一个18位身份验证器,编写验证器,在validators.xml文件中进行注册、在验证配置文件中使用?



步骤一:书写18位身份证的JavaBean类代码:


/**

* 身份证第十八位(效验码)的计算方法

* 将前面的身份证号码17位数分别乘以不同的系数,从第一位到第十七位的系数分别为:

*       7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2

* 计算规则:身份证前十七位与这些系数相乘之和相加,用加出来的和除以11,看余数是多少?余数可能是

*       0, 1,  2 , 3, 4, 5, 6, 7, 8, 9, 10,这十一位数字,其分别对应的最后一位身份证号码为:

*       1, 0, ‘X‘, 9, 8, 7, 6, 5, 4, 3, 2

*

*/

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
;

}

/**

* 该方法是新18位身份证,效验码的计算

*

* 身份证第十八位(效验码)的计算方法

* 将前面的身份证号码17位数分别乘以不同的系数,从第一位到第十七位的系数分别为:

*       7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2

* 计算规则:身份证前十七位与这些系数相乘之和相加,用加出来的和除以11,看余数是多少?余数可能是

*       0, 1,  2 , 3, 4, 5, 6, 7, 8, 9, 10,这十一位数字,其分别对应的最后一位身份证号码为:

*       1, 0, ‘X‘, 9, 8, 7, 6, 5, 4, 3, 2

*/

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

}

/**

* 如果是以前的身份证号码,则将15位的身份证号码,转换为18位的新的身份证号码

* 旧身份证号码规则:(15位)

* 1-6位:地区编码

* 7、8位:出生年的后两位(特点:只能对1900年1月1日到1999年12月31日出生的人编码——千年虫问题)

* 9、10、11、12位:出生月和日,不足两位的高位补零

* 13、14、15位:顺序号,无法确认,15位是性别识别码,男性为奇数,女性为偶数。

*

*/

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

}

}


步骤二:一个18位身份验证器的Java类


package com.atguigu.struts2.validation.app;

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

}

}

}


步骤三:书写validators.xml配置文件(可以参看com.opensymphony.xwork2.validator.validators 下的 default.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">

<!-- START SNIPPET: validators-default -->

<validators>

<validator
name="idcard"
class="com.atguigu.struts2.validation.app.IDCardValidator"/>

</validators>


步骤四:页面展现层的代码:


<s:actionerror/>

idCard: <s:textfield
name="idCard"></s:textfield>

<s:fielderror
fieldName="idCard"></s:fielderror>

<s:submit></s:submit>


这样就实现了服务器后台验证身份证的程序验证器已经部署完成。

时间: 2024-10-15 20:20:53

自定义验证器——用Struts2框架以框架师的思维灵活做好该事情的相关文章

自己定义验证器——用Struts2框架以框架师的思维灵活做好该事情

面对的问题:自己定义一个18位身份验证器.编写验证器.在validators.xml文件里进行注冊.在验证配置文件里使用? 第一部分:理解Struts2中自带的验证器 第二部分:如何通过server(后台).再次对前台的数据进行验证 第三部分:用Struts2来自己定义验证器(问题解决方式) 第一部分:理解Struts2中自带的验证器 Struts2框架中自带的后台server验证分为两种:声明式验证和编程式验证 u  声明式验证(重点) ?  对哪个 Action 或 Model 的那个字段进

Struts2的输入验证(四)-自定义验证器与编程式验证

一.自定义验证器 1.实现步骤: 1)定义一个验证器的类 自定义验证器必须实现 Validator 接口,由于ValidatorSupport 和 FieldValidatorSupport 实现了 Validator 接口,因此可以继承ValidatorSupport 或 FieldValidatorSupport Ⅰ. 若需要普通的验证程序,可以继承 ValidatorSupport 类: Ⅱ. 若需要字段验证程序,可以继承 FieldValidatorSupport 类: Ⅲ. 若验证程序

thinkphp5.0自定义验证器

虽然我早就会些php基础语法,我套过数据,自己写的控制器层,不是用的api方式,那个公司是为了锻炼我,所以才那样做的,基本上的东西都是用的框架自带的,重来自己没有去封装过这些东西,所以编程思想上,还很欠缺,所以我得先好好模仿一下别人的代码. 问题: 如何自定义验证器类,并且如何使用自定义规则; 不管是验证器,还是拦截器,过滤器,都是要先继承相应的类,只要继承了就是对应的什么验证器,拦截器...了; eg: 1.自定义验证器类 class ValidateCustom extends Valida

关于struts2的自定义拦截器和struts2的详细流程

1.其实我们大家平常都会用struts2用的很多,但是有的时候我们并不是真正的了解struts2的运行机制,下面给大家分享一下struts2的运行流程.MVC框架 解释如下: 1.  所有请求被Struts2核心控制器StrutsPreparaedAndExecuteFilter拦截 2.根据ActionMapper提供的信息决定如何进行下一步 3.ActionMapper主要依赖Struts2的配置文件struts.xml 4.接下来为每个Action创建Action代理类ActionProx

自定义验证器

自定义验证器必须实现 Validator 接口. ValidatorSupport 和 FieldValidatorSupport 实现了 Validator 接口 --若需要普通的验证程序, 可以继承 ValidatorSupport 类 --若需要字段验证程序, 可以继承 FieldValidatorSupport 类 --若验证程序需要接受一个输入参数, 需要为这个参数增加一个相应的属性 注册验证程序: 自定义验证器需要在类路径里的某个 validators.xml 文件里注册:  验证框

angular自定义验证器添加入模板驱动表单

创建自定义验证器的命令 ng generate directive forbidden-name(自定义床啊金验证器的名称) 生成的文件内容 import { Directive } from '@angular/core'; @Directive({ selector: '[appForbiddenName]' }) export class ForbiddenNameDirective { constructor() { } } 创建一个文件用来放置正则判断的验证器算法.validatot.

121.自定义验证器

自定义验证器: 有时候我们需要从数据库中提取数据进行验证,这个时候如果还是采用已经定义好的验证器就不能够实现我们想要的功能了.比如我们在注册的时候要验证该手机号或者是邮箱之前是否已经注册过了.如果已经注册过了,就不能够再次进行注册了.这个时候我们就需要对数据库中的手机字段进行验证了.对某个字段进行验证的方式就是,定义一个方法,这个方法的名字的定义规则就是clean_fieldname.如果验证失败,那么就抛出一个错误,如果没有找到相同的手机号就正常情况下返回一个手机号,代表已经通过了验证. (1

JAVAEE——struts2_04:自定义拦截器、struts2标签、登陆功能和校验登陆拦截器的实现

一.自定义拦截器 1.架构 2.拦截器创建 //拦截器:第一种创建方式 //拦截器生命周期:随项目的启动而创建,随项目关闭而销毁 public class MyInterceptor implements Interceptor{} //创建方式2: 继承AbstractInterceptor -> struts2的体贴 //帮我们空实现了init 和 destory方法. 我们如果不需要实现这两个方法,就可以只实现intercept方法 public class MyInterceptor2

枚举帮助方法,枚举数据注解自定义验证器

枚举辅助类 获取枚举项列表 获取枚举值列表 枚举项包含 枚举值包含 转换枚举 代码如下 1 /// <summary> 2 /// 枚举辅助类 3 /// </summary> 4 public class EnumHelper 5 { 6 7 private static readonly Dictionary<Type, object> EnumCache = new Dictionary<Type, object>(); 8 9 private sta