我们的网站是要与用户进行交互的,其中最重要的交互方式便是数据的输入输出。但对于用户来说,并不是会按照我们所期望的形式来进行输入,这是就需要对用户输入的数据的格式进行校验,也就是所谓的数据校验。
其实数据校验意义就是保证进入后台的数据都是安全的!
在大多数情况下我们使用的是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", "年龄不符合人类规范!");
}
//验证邮箱! 123dsaw@163.com
//只允许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>