在jsp表单中经常会出现数据类型转换错误,转换失败后会出现
失败后的解决方法就是配置回显结果视图,从哪里来就回到哪里去。
我们知道继承了ActionSupport类后会有一个validate方法,我们可以重写这个方法进行编程式验证。
@Override
public void validate() {
if(StringUtils.isEmpty(user.getUsername())){
addFieldError("username", "请输入用户名");
}
}
validate方法实现验证的原理是当程序执行到Action时,先判断Action有没有实现validate方法,如果已经实现了,就先执行validate方法,然后执行execute方法,如果还没有实现,就直接执行execute方法。
但编程式验证有一个弊端就是硬编码。
struts2框架自带的校验功能是通过配置文件完成的。它的原理是当程序执行到Action但是还没执行到Action里面的方法时拦截,转而执行校验器,校验器执行完再返回到Action继续执行。struts2中为我们提供了一个验证框架即声明式验证,通过编写验证规则的xml文件,需要验证时,编写xml文件。不需要验证时,不编写。解决了硬编码的弊端,保证客户提交数据的安全性、正确性,其实更重要的是防止攻击
验证器的xml命名方式:
- (全局验证)针对动作类中所有动作进行验证:ActionClassName-validation.xml
- (局部验证)针对动作类中某个动作进行验证:ActionClassName-ActionName-validation.xml 需要注意的是 这里的ActionName是struts.xml中配置的action标签中的name值,不是action类中的方法名
- xml需放在动作类所在的包中
所有的校验器都要放在
标签里,它用来声明校验器。
在使用全局验证时 可以使用 @SkipValidation注解跳过不需要验证的方法。
dtd约束可以从xword核心包里找到 /xwork-validator-1.0.3.dtd 我使用的是1.0.3.dtd约束 自己选择对应的版本
<validators>
<field name="username">
<field-validator type="requiredstring">
<message>请输入用户名!message>
field-validator>
field>
validators>
各校验器的功能说明如下:
名称 | 功能 |
---|---|
required | 用来验证某个给定的字段的值不是null。注意,空字符串不是null |
requiredstring | 验证给定的字段的值既不是null、也不是空格 |
int | 用来验证某个字段的值是否可以被转换为一个整数。若指定参数,还验证是否在允许的范围内 |
long | 用来验证某个字段的值是否可以被转换为一个长整数。若指定参数,还验证是否在允许的范围内 |
short | 用来验证某个字段的值是否可以被转换为一个短整数。若指定参数,还验证是否在允许的范围内 |
double | 用来验证某个字段的值是否可以被转换为一个双精度浮点数。若指定参数,还验证是否在允许的范围内 |
date | 用来确保给定的日期字段的值落在一个给定的范围内 |
expression | 用于验证是否满足一个OGNL表达式。这是一个非字段的验证。只有给定的参数的返回值是true时才能验证通过。验证不通过时产生一个动作错误,因此要显示该错误,需要使用 标签 |
fieldexpression | 用于验证某个字段是否满足一个OGNL表达式。这是一个基于字段的验证。只有给定的参数的返回值是true时才能验证通过。验证不通过时产生一个字段错误 |
用来验证给定的字段是否符合一个Email的规范 | |
url | 用来验证给定的字段值是否是一个合法的URL地址 |
visitor | 该验证程序可以提高代码的可重用性,你可以利用它把同一个验证程序配置文件用于多个动作 |
conversion | 校验字段是否发生转换错误 |
stringlength | 用来验证一个非空的字段值是不是有足够的长度 |
regex | 用来检查给定字段是否与给定的正则表达式相匹配 |
下面用一个小例子来说明struts2验证器的使用
要求如下:
public class User {
private String username;//不能为null和空字符串。要trim
private int age;//整数:介于18-100之间
private String email;//按格式输入
private String password;//长度3~8位
private String repassword;//确认密码 必须和密码一致
private int score;//必须是数字
private String uri;//个人主页,必须符合uri的格式
private String gender;//性别 必须选择一个
/*省略get和set方法*/
}
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<filter>
<filter-name>struts2filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class>
filter>
<filter-mapping>
<filter-name>struts2filter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<welcome-file-list>
<welcome-file>index.jspwelcome-file>
welcome-file-list>
web-app>
<struts>
<constant name="struts.devMode" value="true">constant>
<package name="user" namespace="/user" extends="struts-default">
<action name="register" class="com.scx.web.action.UserAction" method="register">
<result name="input">/index.jspresult>
<result name="success">/success.jspresult>
action>
package>
struts>
public class UserAction extends ActionSupport implements ModelDriven<User>{
/**
*
*/
private static final long serialVersionUID = 1L;
private User user=new User();
@Override
public User getModel() {
return user;
}
public String register(){
System.out.println("注册成功!");
return SUCCESS;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
当程序执行到UserAction还没执行到register方法时进而拦截,从而跳转到UserAction-register-validation.xml进行校验,只有校验成功才会回到register方法,否则进入input视图。
这里的dtd约束可以从xword核心包里找到 /xwork-validator-1.0.3.dtd 我们使用的是1.0.3.dtd约束 自己选择对应的版本
所有的校验器都要放在
标签里,它用来声明校验器。
<validators>
<field name="username">
<field-validator type="requiredstring">
<message>请输入用户名!message>
field-validator>
field>
<field name="age">
<field-validator type="int">
<param name="min">18param>
<param name="max">100param>
<message>请输入范围在18-100的整数message>
field-validator>
field>
<field name="email">
<field-validator type="email">
<message>请输入正确的eamilmessage>
field-validator>
field>
<field name="password">
<field-validator type="requiredstring">
<param name="trim">falseparam>
<message>请输入密码message>
field-validator>
<field-validator type="stringlength">
<param name="minLength">3param>
<param name="maxLength">8param>
<message>请输入3~8位的密码message>
field-validator>
field>
<validator type="expression">
<param name="expression">
param>
<message>两次密码必须一致message>
validator>
<field name="score">
<field-validator type="regex">
<param name="regex">
\d+
param>
<message>请输入正确的成绩message>
field-validator>
field>
<field name="uri">
<field-validator type="url">
<message>请输入正确的url地址message>
field-validator>
field>
<field name="gender">
<field-validator type="required">
<message>请选择性别message>
field-validator>
field>
validators>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<title>验证信息title>
<s:head/>
head>
<body>
<s:actionerror/>
<s:form action="/user/register.action">
<s:textfield name="username" label="用户名" requiredLabel="true" requiredPosition="left"/>
<s:textfield name="age" label="年龄"/>
<s:textfield name="email" label="邮箱"/>
<s:textfield name="password" label="密码"/>
<s:textfield name="repassword" label="确认密码"/>
<s:textfield name="score" label="成绩"/>
<s:textfield name="uri" label="个人主页"/>
<s:radio name="gender" label="性别" list="{'男','女'}"/>
<s:submit label="注册">s:submit>
s:form>
body>
html>