一、前言
1.1、什么是输入验证?为什么需要输入验证?
在上一篇文章中,我们学习了数据类型转换,我们提到了表示层数据处理的两个方法,也提到了用户输入数据需要进行类型转换才能得到我们想要的数据,那么,我们怎么确定类型转换后的数据,是我们想要的数据呢?这里有点绕。你可以这样想:一个成年男子年龄是18岁,你现在想要得到18这个数据,但是,用户输入32,经过类型转换也是对的,但是数据不是你想要的。这时候,我们要怎么办?所以输入验证在这里就有用处了。
类型转换和输入验证的关系是:类型转换是输入验证的前提,如果类型转换都出错了,那就不用再进行输入验证了。但是很多时候类型转换和输入验证是同时完成的。
输入验证有两种:
1、客户端验证;
2、服务端验证。这里主要讲解的是服务端验证(重写ValidateXxx方法和xml配置文件验证)
1.2、重写ValidateXxx方法的验证流程
1、类型转换器负责对字符串的请求参数进行类型转换,并将这些值设置成Action的属性值
2、在执行类型转换过程中可能出现异常,如果出现异常,异常信息会自动保存到ActionContext中,conversionError拦截器负责将其封装到fieldError中
3、通过反射调用ValidateXxx()方法,其中Xxx是即将处理用户请求的处理逻辑所对应的方法名
4、调用Action类的Validate方法
5、如果上面的步骤没有出现fieldError,将调用Action里处理用户请求的处理方法,如果出现fieldError,系统将转入input逻辑视图所指定的视图。
二、输入验证
2.1、输入验证这里讲解的有两种方式:
1、重写Validate方法或者自定义ValidateXxx方法(其中的Xxx是自己定义的名字,会先执行该方法,在执行Validate方法)
2、新建xml进行验证
2.2、重写Validate方法
在MVC框架,都会提供规范的数据验证部分,Struts2在这里提供的是一个Validate方法,我们重写Validate方法就可以进行输入验证,但是,重写Validate方法有两个点需要知道:1、Validate方法会在execute方法之前被执行;2、Validate方法对所有的Action都会执行校验规则,为了区别某一个Action,我们可以使用ValidateXxx方法。
注意:以下的例子是局部类型转换和输入验证一起使用的例子。
简单的注册验证例子:
新建实体类User:
User
新建视图:Register.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<%@ page language= "java" contentType= "text/html; charset=UTF-8" pageEncoding= "UTF-8" %> <%@ taglib uri= "/struts-tags" prefix= "s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" > <html> <head> <meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" > <title>注册用户</title> </head> <body> <h2>使用validateXXX()方法验证</h2> <form action= "register_test" > 用户:<input type= "text" name= "user" ><br/> 密码:<input type= "password" name= "user" ><br/> 密码:<input type= "password" name= "user" ><br/> <input type= "submit" value= "提交" > </form> </body> </html> |
新建RegisterAction类继承ActionSupport
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package com.validatexxx; import com.opensymphony.xwork2.ActionSupport; //重写validate()和validateXXX指定方法进行验证 /* * 在struts.xml配置method方法为test(),会先调用ValidateTest()方法, * 然后在调用validate方法 * 之后test方法被调用 * */ public class RegisterAction extends ActionSupport { private User user; public User getUser() { return user; } public void setUser(User user) { this .user = user; } //2 @Override public void validate(){ System.out.println( "重写Validate方法" ); if ( null == user.getPassword() || "" .equals(user.getPassword()) || null == user.getRepassword() || "" .equals(user.getRepassword())) { this .addFieldError( "repassword" , "repassword should be same password" ); return ; } if (!user.getPassword().equals(user.getRepassword())) { //当FieldError中存在数据时,服务器会自动帮我们跳转到input的逻辑视图 this .addFieldError( "repassword" , "repassword should be same password" ); } } //1 public void validateTest(){ System.out.println( "自定义校验方法:ValidateTest" ); } //3 public String test(){ System.out.println( "test:方法" ); return SUCCESS; } } |
注意:这里的属性是User,所以你jsp页面参数的名字要写实例的名字user,然后你还需要去创建一个类型转换器,返回一个填充好数据的类
新建struts.xml,存放在WEB-INF/classes/struts.xml
注意:这里的method必须是你ValudateXxx()方法后面你自己定义的,笔者这里是test。使用*的话,struts2还必须配置 strict-method-invocation="false",据说是因为版本太高了,它的安全性增加了,所有必须加才能够使用*
新建Usertypeconverter类继承StrutsTypeConverter(创建一个类型转换器)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
package com.validatexxx; import java.util.Map; import org.apache.struts2.util.StrutsTypeConverter; //类型转换的类 public class Usertypeconverter extends StrutsTypeConverter { @Override public Object convertFromString(Map arg0, String[] arg1, Class arg2) { System.out.println( "Usertypeconverter:类型转换!" ); User user = new User(); user.setUsername(arg1[ 0 ]); user.setPassword(arg1[ 1 ]); user.setRepassword(arg1[ 2 ]); return user; } @Override public String convertToString(Map arg0, Object arg1) { User u = (User)arg1; return u.getUsername()+ "!" ; } } |
注意:该类型转换器创建好之后还需新建一个RegisterAction-conversion.properties,放在同级目录下
该文件的内容有:
前面是你在RegisterAction的属性名,后面是类型转换器的具体路径。
新建成功视图:success.jsp
success.jsp
新建错误视图:input.jsp
input.jsp
代码执行成功的效果如下:
Register.jsp页面
成功跳转的页面为:success.jsp
控制台测试结果为:
数据跳转到Usertypeconverter进行类型转换,之后跳转到RegisterAction,执行ValidateTest方法(),Validate,test之后返回SUCCESS,然后执行result的视图。
我们看代码执行失败的顺序:
Register.jsp页面
input.jsp页面
控制台测试效果:
在Validate方法里面,笔者代码为:this.addFieldError(),在前面有说过,如果添加错误的话,那么服务器会自动帮我们跳转到错误的界面。它会返回input,而input在struts.xml中就有配置,会返回到input.jsp界面。
2.3、新建xml进行输入验证
新建视图界面:Test.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<%@ page language= "java" contentType= "text/html; charset=UTF-8" pageEncoding= "UTF-8" %> <%@ taglib uri= "/struts-tags" prefix= "s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" > <html> <head> <meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" > <title>使用XML校验</title> </head> <body> <s:form action= "empinfo" method= "post" > <s:textfield name= "name" label= "Name" size= "20" /> <s:textfield name= "age" label= "Age" size= "20" /> <s:submit name= "submit" label= "Submit" align= "center" /> </s:form> </body> </html> |
新建Employee类继承ActionSupport
该类有使用重写Validate方法和Xml配置,我们可以选择其中一种进行验证就可以
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
package com.validatexxx; import com.opensymphony.xwork2.ActionSupport; //使用validate()方法验证,这是服务端验证! public class Employee extends ActionSupport { private String name; private int age; public String getName() { return name; } public void setName(String name) { this .name = name; } public int getAge() { return age; } public void setAge( int age) { this .age = age; } //第二步再执行该方法 public String execute(){ System.out.println( "execute:" + this .age); return SUCCESS; } /* 使用服务端的校验:重写validate方法(); //第一步先执行该方法 //重写validate方法有缺陷:每次都会使用validate方法验证,造成极大的资源浪费。 public void validate(){ System.out.println("validate"); if (name == null || name.trim().equals("")) { //当往该方法添加数据的时候,服务器会返回input,之后跳转到input.jsp页面中。 addFieldError("name","The name is required"); } if (age < 28 || age > 65) { addFieldError("age","Age must be in between 28 and 65"); } } */ } |
在Struts.xml中进行配置:
这里的success.jsp和input.jsp还是使用上面的。
之后我们需要新建Employee-validation.xml,路径放在与Employee同级目录下,注意:-validation.xml是固定不变的
内容为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?xml version= "1.0" encoding= "UTF-8" ?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd" > <validators> <field name= "name" > <field-validator type= "required" > <message> The name is required. </message> </field-validator> </field> <field name= "age" > <field-validator type= "int" > <param name= "min" > 29 </param> <param name= "max" > 64 </param> <message> Age must be in between 28 and 65 </message> </field-validator> </field> </validators> |
重点:该文件的dtd限制必须有,不然回报错误:
ERROR DefaultDispatcherErrorHandler Exception occurred during processing request: [Connection timed out: connect - [unknown location], null]
接下来我们使用http://localhost:8080/LearStruts2/ValidateJSP/Test.jsp进行访问。
测试成功:
Test.jsp界面:
success.jsp
测试失败例子:
input.jsp界面:
说明例子是正确的。
其实在Struts2中有多个内置验证器:必填验证器,必填字符串验证器,整数验证器,日期验证器,表达式验证器,字符长度验证器,正则表达式验证器...等等,这个有需要的话,笔者在一一述说。
以上所述是小编给大家介绍的Struts2数据输入验证教程详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:http://www.cnblogs.com/yingzi1028/p/5976774.html