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

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

第二部分:如何通过server(后台)。再次对前台的数据进行验证

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

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

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

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>

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvbmd3ZW43NzEw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

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

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

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

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvbmd3ZW43NzEw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

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、不同的字段使用相同的验证规则, 并且使用相同的响应消息 ?

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvbmd3ZW43NzEw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvbmd3ZW43NzEw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

第二部分:如何通过server(后台)。再次对前台的数据进行验证

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

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文件里进行注冊、在验证配置文件里使用?

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvbmd3ZW43NzEw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

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

/**

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

位数分别乘以不同的系数,从第一位到第十七位的系数分别为:

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

。看余数是多少?余数可能是

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

}

/**

位身份证。效验码的计算

*

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

位数分别乘以不同的系数,从第一位到第十七位的系数分别为:

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

,看余数是多少?余数可能是

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

}

/**

位的新的身份证号码

位)

位:地区编码

日出生的人编码——千年虫问题)

位:出生月和日,不足两位的高位补零

位是性别识别码,男性为奇数,女性为偶数。

*

*/

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>

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

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

  1. 9、 Struts2验证(声明式验证、自定义验证器)

    1. 什么是Struts2 验证器 一个健壮的 web 应用程序必须确保用户输入是合法.有效的. Struts2 的输入验证 基于 XWork Validation Framework 的声明式验证: ...

  2. Struts(二十五):自定义验证器

    编程验证 Struts2提供了一个Validateable接口,可以使用Action类实现这个接口以提供编程验证: ActionSupport类已经实现了Validateable接口. public ...

  3. 自定义基于XML的验证器

    a.编写一个类,继承FieldValidatorSupport类. b.在public void validate(Object object)编写你的验证逻辑 不符合要求的就向fieldErrors ...

  4. TP5 自定义验证器

    TP内置验证功能提供两种验证方法 验证器(推荐) $validate = Validate::make([ 'id' => 'require|integer', ]); if ($validat ...

  5. flask 自定义验证器(行内验证器、全局验证器)

    自定义验证器 在WTForms中,验证器是指在定义字段时传入validators参数列表的可调用对象,下面来看下编写自定义验证器. 行内验证器 除了使用WTForms提供的验证器来验证表单字段,我们还 ...

  6. form——验证器Validators

    form表单最大的作用就是验证功能了,通过cleaned_data清洗,我们可以获取传来的值,通过参数.验证器.自定义验证方法,我们可以做到很多的验证. 验证器可用于在不同类型的字段之间重用验证逻辑. ...

  7. ThinkPHP6.0学习笔记-验证器

    验证器 By:Mirror王宇阳 验证器定义 验证器的使用,必须定义它:系统提供了一条命令直接生产一个验证器类: php think make:validate User 自动再应用目录下生成一个va ...

  8. 基于struts2框架-自定义身份证号验证器

    自定义拦截器的步骤: 1.定义一个验证器的类: > 自定义的验证器都需要实现 Validator接口.  > 可以选择继承 ValidatorSupport 或 FieldValidato ...

  9. struts2验证器

    1. Struts2 的验证(note6,struts2-8) 1). 验证分为两种: > 声明式验证* >> 对哪个 Action 或 Model 的那个字段进行验证 >&g ...

随机推荐

  1. Fortran学习记录1(Fortran数据类型)

    Fortran中的字符 Fortran中的常量 Fortran中的变量 Fortran的I-N规则 Fortran中的有效位数 Fortran中的申明 Fortran中的表达式 Fortran中的语句 ...

  2. Openjudge-4132-四则运算表达式求值

    这一题我们可以通过递归求解,首先我们可以把一个表达式分为三部分,分别是: (1)表达式 :项.加减 (2)项:因子.乘除 (3)因子:数.()表达式 这三项构成了递归的关系,我们可以看到,要求一个表达 ...

  3. LinkedList集合(JDK1.8)

    简述 按照上篇笔记ArrayList集合继续进行介绍list的另一个常见子类LinkedList ?LinkedList介绍 1.数据结构 说明:linkedlist的底层数据结构是个双向链表结构,也 ...

  4. Django 动态建表

    #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Random_lee # -*- coding: utf-8 -*- from django ...

  5. django1.11 启动错误:Generator expression must be parenthesized

    错误信息: Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0 ...

  6. Java基础学习总结(94)——Java线程再学习

    Java线程有哪些不太为人所知的技巧与用法? 萝卜白菜各有所爱.像我就喜欢Java.学无止境,这也是我喜欢它的一个原因.日常工作中你所用到的工具,通常都有些你从来没有了解过的东西,比方说某个方法或者是 ...

  7. 大数据学习——hive显示命令

    show databases; desc t_partition001; desc extended t_partition002; desc formatted t_partition002; !c ...

  8. Go常量与枚举类型

    package main import ( "math" "fmt" ) //常量与枚举 //const数值可作为各种类型使用 func consts() { ...

  9. C#特性入门《详解》

    原文发布时间为:2008-11-22 -- 来源于本人的百度文章 [由搬家工具导入] <转>http://www.bccn.net/Article/net/cs/jszl/200709/6 ...

  10. JVM内存区域(运行时数据区)划分

    前言: 我们每天都在编写Java代码,编译,执行.很多人已经知道Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文 ...