表单数据验证是很常见的功能,通常前端页面会有一次 js验证,但是后台也需要进行一次验证,这不依赖于前台验证,是保险的做法。
同时,我们后台验证输入数据的合法性,如果按照以前的servlet方法,显而易见是非常麻烦的,我们既要获取表单数据,又要进行String类型的表单数据进行数据类型转换,再进行数据合法性验证,然后还要将非法数据的提示信息打印到页面上提示用户输入非法,这显得很忙,很累。
因此,Struts2为我们提供了一些数据验证手段,特别是Struts2的验证框架, 可以有效为我们减少重复性的操作,非常值得学习。
1.Action重写的validate()方法或使用validateXXX()方法
validate的意思就是验证。我们的Action通常会集成ActionSupport这个类,这个类有很多有用的方法,其中,validate()验证方法就是其中之一。validate()方法会在action前自动执行。
这样重写validate()方法后,对于Action里的任何方法,都会先执行validate()方法验证。实际上,一个Action里会有很多个方法,但是并不是每个方法都需要同样的验证方式,因此,就出现了根据方法不同设定不同验证方法的方式。
validateXXX(),可以针对特定的方法使用特定的验证方法,其余没有什么变化。这个方法直接定义即可,同样会在XXX()方法前执行验证。
如果两个验证方法都存在,执行顺序是先执行validateXXX(),再执行通用的validate()方法。
validateAction
public class ValidateAction extends ActionSupport {
private String username;
private String password;
@Override
public String execute() throws Exception {
return super.execute();
}
public String test() throws Exception{
return "success";
}
public void validateTest(){
System.out.println("test单独验证中");
if(getUsername()==null||"".equals(getUsername().trim())){
this.addFieldError("usernameMsg", "用户名不能为空!");
}else {
Pattern p = Pattern.compile("\\{6,20}");
Matcher m = p.matcher(getUsername().trim());
if(!m.matches()){
this.addFieldError("usernameMsg","用户名有下划线,字母,数字构成,长度6-20");
}
}
}
@Override
public void validate() {
System.out.println("全局验证中");
if(getUsername()==null||"".equals(getUsername().trim())){
this.addFieldError("usernameMsg", "用户名不能为空!");
}else {
Pattern p = Pattern.compile("\\{6,20}");
Matcher m = p.matcher(getUsername().trim());
if(!m.matches()){
this.addFieldError("usernameMsg","用户名由下划线,字母,数字构成,长度6-20");
}
}
if(getPassword().trim().length()==0){
this.addFieldError("passwordMsg","密码不能为空!");
}else{
int s = getPassword().trim().length();
if(s<6 || s>30){
this.addFieldError("passwordMsg","密码长度应在6-30之间");
}
}
}*/
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;
}
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--用于输出提示信息,必须的--%>
<s:fielderror></s:fielderror>
<s:form name="form1" action="validateAction.action" method="post" validate="true">
<s:textfield name="username" label="用户名"/>
<s:textfield name="password" label="密码"/>
<s:submit value="登陆"/>
</s:form>
</body>
</html>
strtus.xml片段
<action name="validateAction" class="com.zsb.action.ValidateAction" method="test">
<result name="success">success.jsp</result>
<!--配合validate方法的result,确定验证失败后的去向-->
<result name="input">validateLogin.jsp</result>
</action>
2. 使用Struts2验证框架
尽管使用validate()方法比起自己实现验证要方便的多,但是依然存在代码不能重用的缺点,很多aciton方法都需要同样的验证,但又要在不同的action里重复写多次validate()方法。
因此,就出现了Struts2的验证框架。
本来,还以为很简单的,但是,使用了校验框架后,却一直没有效果。
对于校验文件的头部,我在struts2-core的包里找到了。
校验文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!--这个头部最好到struts2-core里复制-->
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<!--有两种方式,这里使用字段校验,是针对一个字段列举所有的需要的校验器,
其实是一样的,只是以谁为中心,另一种是非字段校验,是针对一个校验器列举所
有的需校验字段-->
<!--strtus2内置了很多校验器,也可以会用正则表达式。这里只列举了
非空字符串验证器,字符串长度验证器-->
<validators>
<field name="username">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>用户名不能为空</message>
</field-validator>
</field>
<field name="password">
<field-validator type="requiredstring">
<message>密码不能为空</message>
</field-validator>
<field-validator type="stringlength">
<param name="minLength">6</param>
<param name="maxLength">15</param>
<message>密码长度6-15位</message>
</field-validator>
</field>
</validators>
目录:
struts.xml配置(没有变动):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="login" namespace="/" extends="struts-default">
<action name="validateAction" class="com.zsb.action.ValidateAction">
<result name="success">success.jsp</result>
<result name="input">validateLogin.jsp</result>
</action>
</package>
</struts>
对于struts2,我了解到它出现了两次高危漏洞,就算以后再用,也肯定要升级到2.5的,因此暂时没有试验低版本struts2。