咳咳,Struts2的验证(Validation)框架昨天纠结了N久啊,还是借助官方的文档,这次使用的是Basic Validation,官方的一个example,主要通过xml文件对用户的输入(是否为空、输入范围)进行验证。我第一次看的时候以为蛮简单,结果折腾到晚上11点才弄出来,应用到自己的期末课设那更狼狈QAQ,凌晨1点依然无果,刚刚才解决,赶快记录下来。
一、关于Struts2的验证框架(Validation)
Struts2提供了一套丰富的验证框架,可以验证用户输入是否为空、数字、email、日期等,甚至可以自定义正则表达式,官方提供了两种方式,一种是通过XML文件,还有一种是通过注释(annotations),本篇主要讲前者,对于XML方式的验证,还有两个分支,一种是域验证(Field Validation),还有一种是无域验证(Non Field Validation),显然前者的作用域更小,只针对于某个Action。本篇针对前者,也就是域验证。
二、实例:使用XML方式的域验证方式验证用户输入是否为空
这里我就用我的Java EE课设来做说明吧,我们要做的是在登陆时验证用户输入是否为空
1、我们先建立一个登陆页Login.jsp,代码如下,可忽略我的CSS文件,但是<s:head/>最好加上,这个标签会自动填上一个CSS样式和JS脚本,为
<link rel="stylesheet" href="/javaEE-final/struts/xhtml/styles.css" type="text/css"/>
<script src="/javaEE-final/struts/utils.js" type="text/javascript"></script>
其中,CSS文件中定义了一些显示Validation错误的样式,CSS类名为errorMessage,JS文件在本实例中的作用为生成错误提示,动态写入HTML代码嘛~ javaEE-final是我的项目名,这些路径都是自动生成的。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!-- 快速建站 灵感来自Bootstrap哈哈哈-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>学生信息管理系统</title>
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="css/login.css" rel="stylesheet" />
<s:head/>
</head>
<body>
<s:fielderror/>
<div class="container">
<form class="form-signin" action="login" method="post">
<h2 class="form-signin-heading">用户登陆</h2>
<input type="text" class="form-control" placeholder="姓名拼音缩写" name="userName" >
<br/>
<input type="password" class="form-control" placeholder="密码" name="password">
<input type="submit" value="登陆" class="btn btn-lg btn-primary btn-block">
</form>
</div>
</body>
</html>
2、建包org.myweb.authority,在包中建Action,LoginAction.java,我使用login替代execute作为运行方法
一定要继承ActionSupport类,否则控制台会抛出诸如此类错误
严重: Validation error for password:密码不能为空
导致验证框架无法启动
代码如下:
package org.myweb.authority;
/*
* 登陆Action
* Written By 小远
* 2016-12-07
*
*/
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import org.myweb.dao.Dao;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
//登陆Action
public class LoginAction extends ActionSupport{
String userName = "";//用户名
String password = "";//密码
/********************各变量的get set方法**************************************/
public void setUserName(String userName) {
this.userName = userName;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return password;
}
public String getUserName() {
return userName;
}
/*******登陆Action********/
public String login()
{
ActionContext actionContext = ActionContext.getContext();//Action上下文,用于获取和设置Session
Dao dao = new Dao();
try {
//先根据用户名和密码查询
PreparedStatement state = dao.getConn().prepareStatement("select * from user where loginName = ? and password = ?");
state.setObject(1,userName);
state.setObject(2, this.password);
ResultSet rs = dao.executeQuery(state);
Map session = actionContext.getSession();//通过继承来的ActionContext获取Session对象
session.put("loginName", userName);
if(rs.next())//如果有对应记录
{
session.put("user", rs.getObject(2));//设置真实姓名,用于JavaBean构造实体
String identity = rs.getString(4);//获得用户身份
//根据身份进行跳转
if(identity.equals("1"))
{
session.put("id", rs.getObject(1));
return "TEACHER";
}
else if(identity.equals("0"))
{
session.put("id", rs.getObject(1));
return "STUDENT";
}
return "OK";
}
return "FAILD";
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "FAILD";
}
}
}
3、建立XML文件
注: XML文件不能随便建,命名和安放位置都有讲究,因为我们做的是针对某个Action的局部的域验证,官方指出
Per Action class: in a file named ActionName-validation.xml
这句话点出了命名规则,为ActionName-validation.xml,其中ActionName为我们需要做验证的Java类名!
官方倒是没有具体指出安放位置,这个比较头疼,我就想吧,既然是对每个Action的验证,那么就应该跟java文件放在一起,结果我用官方的例子试了一下发现还真是~
XML文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!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>用户名不能为空</message>
</field-validator>
</field>
<field name="password">
<field-validator type="requiredstring">
<message>密码不能为空</message>
</field-validator>
</field>
</validators>
其中field name的值为你要验证的某个表单元素的name值,field-validator表明我们是使用域验证模式,type属性为requiredstring,表示要求用户需输入,
虽然官方有个required,但是不适用这种情况咩,还是会验证通过。message是验证不通过时提示用户的信息。
此时,org.myweb.authority的结构如下
4、配置Struts.xml
关键内容如下:
<package name="/" namespace="/" extends="struts-default">
<action name="login" class="org.myweb.authority.LoginAction" method="login">
<result name="TEACHER" type="redirect">/Teacher/index.jsp</result>
<result name="STUDENT" type="redirect">/Student/index.jsp</result>
<result name="FAILD" type="redirect">/Login.jsp</result>
<result name="input">/Login.jsp</result>
</action>
</package>
input的result一定要有!因为我们继承了struts-default.xml,其中默认有一个拦截器栈,在这个栈结构中,定义了一个叫workflow的拦截器,在验证过程中,input的result就是由这个拦截器抛出的。
最后,不要忘了,把WEB-INF下的Struts2的过滤器设置成如下内容,原来他默认Action的后缀是.action的,这个主要看开发者,我是习惯这样滴~
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
5、运行看效果
5、扩展,Struts2的的验证框架有很多,可以官方或者度娘搜索看看
比如验证数字输入范围,可以如下配置验证XML文件
<field name="age">
<field-validator type="int">
<param name="min">13</param>
<param name="max">19</param>
<message>Only people ages 13 to 19 may take this quiz</message>
</field-validator>
</field>
param的两个属性,max和min规定了用户可以输入的最大值和最小值
6、注意事项
昨天我在给其他页面增加验证框架的时候发现一个问题,比如登陆,整个过程变得奇慢无比,而且所有的验证提示都消失了,并且myEclipse后台报错,大概是Caught exception while loading file XXX.xml,后来查了一下,把所有XXX-validation.xml文件的头由
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
改成
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
即可