我们的网站是要与用户进行交互的,其中最重要的交互方式便是数据的输入输出。但对于用户来说,并不是会按照我们所期望的形式来进行输入,这是就需要对用户输入的数据的格式进行校验,也就是所谓的数据校验。
其实数据校验意义就是保证进入后台的数据都是安全的!
在大多数情况下我们使用的是JavaScript来进行输入数据的校验,但是这种方式具有局限性
如图所示:我们可以通过使用url拼接的方式直接将数据传到后台去,这时的数据校验便失去了意义。
所以单纯通过js无法满足我们的安全要求。
目前主流的web层框架都具备校验的相关功能,我们的Struts2提供了两种较为简易的校验方式:
- 硬编码方式---易理解、不易维护
- xml配置方式---易维护、易管理、不侵入源代码(推荐)
下面我们以一个注册为例,讲解一下两种方式验证流程
我们要验证的数据为:
用户名:要求 不能为空!大于6位小于11位
密码:要求 不能为空!大于6位小于11位 两次密码一致
年龄:要求 0-150岁
邮箱:要求 不能为空!必须符合邮箱格式
电话:要求 不能为空!必须是电话格式(1(3/5/8)xxxxxxxx,或010-xxxxxxxx或 0531-xxxxxxxx)
首先我们使用硬编码方式校验
硬编码方式实现步骤:
第一步:创建Struts2项目
第二步:编写一个普通表单
第三步:在jsp中加入标签库支持
第四步:jsp中加入struts2校验框架提供的两种校验级别错误:
属性级错误: <s:fielderrorcssStyle="color:red;"/>
Action级错误:<s:actionerrorcssStyle="color:red;"/>
通常属性校验失败我们将错误信息放入fielderror对象中,action级别错误信息放入actionerror 对象中。
第五步:创建Action类,配置到struts.xml中
注意一定要配置一个result,name值为input,用于验证失败跳转页面
第六步:Action类中创建校验方法,方法命名规则:
validate+要验证的方法名(首字母大写)
(例如:execute()方法,校验方法validateExecute())
假如action中有很多方法,也可以分开验证。
第七步:完善校验方法中具体的判断
错误信息共分为两种:FieldError和ActionError
将错误信息放入Field域中:
this.addFieldError("username","用户名不能为空");
将错误信息放入Action域中:
this.addActionError("请两次密码必须一致");
实际上会将错误信息放入Struts2默认栈队map集合中
页面可以使用 ${errors.username[0]}来单独展示属性错误信息
复杂验证例如邮箱、电话等判断需要用到正则表达式!
用到的界面代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <head> <title>index</title> </head> <body> <s:fielderror cssStyle="color: red"/><br> <s:actionerror cssStyle="color: red;"/><br> <hr/> <form method="post" action="ch07RegisterAction.action"> <%--错误信息内部存储方式是数组,为防止一个表单元素有多个属性--%> <%--对象方式页面错误信息的编写方式有所不同--%> 账号:<input type="text" name="users.username"/>${errors["users.username"][0]}<br> 密码:<input type="password" name="users.password"/>${errors["users.password"][0]}<br> 重新输入密码:<input type="password" name="users.repassword"/>${errors["users.repassword"][0]}<br> E-mail:<input type="text" name="users.email"/>${errors["users.email"][0]}<br> 手机号:<input type="text" name="users.phonenumber"/>${errors["users.phonenumber"][0]}<br> 年龄:<input type="text" name="users.age"/>${errors["users.age"][0]}<br> <input type="submit" value="提交"/> </form> </body> </html>
ValidateAction类
package cn.lovepi.chapter07.action; import com.opensymphony.xwork2.ActionSupport; import java.util.regex.Pattern; /** * * 数据校验示例——硬编码格式 */ public class ValidateAction extends ActionSupport{ private String username; private String password; private String repassword; private String email; private String phonenumber; private int age; @Override public String execute() throws Exception { return SUCCESS; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRepassword() { return repassword; } public void setRepassword(String repassword) { this.repassword = repassword; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhonenumber() { return phonenumber; } public void setPhonenumber(String phonenumber) { this.phonenumber = phonenumber; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }配置当前的Action
<package name="chapter07" extends="struts-default"> <!--硬编码配置数据校验--> <action name="ch07ValidateAction" class="cn.lovepi.chapter07.action.ValidateAction"> <result name="success">/chapter07/index.jsp</result> <!--必须配置,用于数据校验出错时跳转--> <result name="input">/chapter07/index.jsp</result> </action> </package>ValidateAction 类种对应的校验方法
public void validateExecute(){ if (null==username || username.length()<6 ||username.length()>10) { this.addFieldError("username", "username has error"); } if (null==password || password.length()<6||password.length()>10) { this.addFieldError("password", "password has error"); }else if (null==repassword || repassword.length()<6||repassword.length()>10) { this.addFieldError("repassword", "repassword has error"); }else if(!password.equals(repassword)){ this.addFieldError("password", "tow password is not be same"); } if (age<=0 ||age>150) { this.addFieldError("age", "年龄不符合人类规范!"); } //验证邮箱! [email protected] //只允许a-z A-Z 1-9 -_ //正则表达式---专门用于复杂字符判断的技术。可以应用于所有软件编程语言 Pattern p = Pattern.compile("^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\\.([a-zA-Z0-9_-])+)+$"); if (null==email || !p.matcher(email).matches()) { this.addFieldError("email", "邮箱验证失败!"); } Pattern p1=Pattern.compile("^(((13[0-9])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8})|(0\\d{2}-\\d{7,8})|(0\\d{3}-\\d{7,8})$"); if (null==phonenumber || !p1.matcher(phonenumber).matches()) { this.addFieldError("phonenumber", "电话格式不正确!"); this.addActionError("action级别错误!"); //这些错误信息被默认放入struts2默认的栈队中。Map集合errors } }
xml配置方式校验
Xml配置方式实现步骤:
第一步:创建Struts2项目,创建实体类Users
第二步:编写一个普通表单
第三步:在jsp中加入Struts2标签库支持
第四步:jsp中加入Struts2校验框架提供了两种校验级别错误:
属性级错误: <s:fielderrorcssStyle="color:red;"/>
Action级错误:<s:actionerrorcssStyle="color:red;"/>
单属性方式页面错误信息:${errors.username[0]}
对象方式页面错误信息:${errors["user.username"][0]}
第五步:创建Action类,配置到struts.xml中
注意一定要配置一个result,name值为input,用于验证失败跳转页面
RegisterAction类
第六步:在action类同包下创建一个Xml配置文件,该文件用于写校验信息
命名规则:Action名-validation.xml(例:UserAction-validation.xml)
第七步:编写UserAction-validation.xml校验信息
User类
public class Users { private String username; private String password; private String repassword; private String email; private String phonenumber; private int age; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRepassword() { return repassword; } public void setRepassword(String repassword) { this.repassword = repassword; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhonenumber() { return phonenumber; } public void setPhonenumber(String phonenumber) { this.phonenumber = phonenumber; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }用到的界面和上面一样
RegisterAction类
public class RegisterAction extends ActionSupport{ private Users users; @Override public String execute() throws Exception { return SUCCESS; } public Users getUsers() { return users; } public void setUsers(Users users) { this.users = users; } }
配置文件编写
<package name="chapter07" extends="struts-default"> <!--xml配置数据校验--> <action name="ch07RegisterAction" class="cn.lovepi.chapter07.action.RegisterAction"> <result name="success">/chapter07/success.jsp</result> <result name="input">/chapter07/index.jsp</result> </action> </package>UserAction-validation.xml 校验信息
<?xml version="1.0" encoding="UTF-8"?> <!--注意这里的代码在对应的/lib/xwork-core.jar/xwork-validator-1.0.3.dtd中 使用1.0.2执行报错--> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <!--具体需求验证代码--> <validators> <!--对username属性进行验证--> <field name="users.username"> <!--具体验证器,验证属性不能为空--> <field-validator type="requiredstring"> <!--去空格--> <param name="trim">true</param> <!--错误信息--> <message>用户名不能为空</message> </field-validator> <!--使用正则表达式进行验证,验证账户名只能为数字或字母,并且长度在6-25之间--> <field-validator type="regex"> <param name="regex"> <![CDATA[(\w{6,25})]]> </param> <message>账号只能是数字或字母,并且长度得在6-25之间</message> </field-validator> </field> <!--对password属性进行验证--> <field name="users.password"> <field-validator type="requiredstring"> <param name="trim">true</param> <message>密码不能为空</message> </field-validator> <field-validator type="stringlength"> <param name="minLength">6</param> <param name="maxLength">18</param> <message>密码长度得在6-18位之间</message> </field-validator> <!--注意这里得用fieldexpression来比较两个属性之间的关系--> <field-validator type="fieldexpression"> <param name="expression"> <![CDATA[(users.password==users.repassword)]]> </param> <message>两次密码必须一致</message> </field-validator> </field> <!--对age属性进行验证--> <field name="users.age"> <field-validator type="int"> <param name="min">0</param> <param name="max">150</param> <message>年龄不合法</message> </field-validator> </field> <!--对邮箱属性进行验证--> <field name="users.email"> <field-validator type="email"> <message>邮箱格式不正确</message> </field-validator> </field> <!--对手机号码进行验证--> <field name="users.phonenumber"> <field-validator type="regex"> <param name="regex"> <![CDATA[ ^(((13[0-9])|(15([0-3]|[5-9]))|(18[0,5-9]))\d{8})|(0\d{2}-\d{7,8})|(0\d{3}-\d{7,8})$ ]]> </param> <message>手机号码格式错误</message> </field-validator> </field> </validators>