Struts2输入校验之validate输入校验方式

一.在Web系统项目中有大量的视图页面需要用户自行输入很多数据。这些数据的类型有很多种。为了防止某些客户的恶意输入以及对Web项目的恶意破坏,必须引入输入校验,像Windows操作系统的防火墙一样把一些垃圾数据过滤掉,挡在Web系统之外。接下来就来介绍一下validate输入校验方式:

1.validate方法进行输入校验:这里直接附上一个简单的用户注册功能具体介绍利用validate方法对数字、字符串、日期等类型数据进行输入校验方式介绍:

(1).首先,新建一个Struts2项目InputValidate,项目结构图如下:




(2).新建一个注册页面,register.jsp页面,用于输入校验的输入数据,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'register.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>

<body>
	<s:form action="register" namespace="/">
		<s:textfield name="username" label="用户名"></s:textfield>
		<s:password name="password" label="密码"></s:password>
		<s:password name="password1" label="密码确认"></s:password>
		<s:textfield name="birthday" label="生日"></s:textfield>
		<s:textfield name="mobile" label="手机号码"></s:textfield>
		<s:textfield name="age" label="年龄"></s:textfield>
		<s:submit value="注册"></s:submit>
	</s:form>
</body>
</html>


(3).新建一个Action类,RegisterAction类,代码如下:

package com.gk.action;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

public class RegisterAction extends ActionSupport {
	private String username;
	private String password;
	private String password1;
	private Date birthday;
	private String mobile;
	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 getPassword1() {
		return password1;
	}

	public void setPassword1(String password1) {
		this.password1 = password1;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String execute() {
		return SUCCESS;
	}

	public void validate() {
		if (getUsername() == null || getUsername().trim().equals("")) {
			addFieldError("username", "请输入用户名");
		}
		if (getPassword() == null || getPassword().trim().equals("")) {
			addFieldError("password", "请输入密码");
		}
		if (getPassword1() == null || getPassword1().trim().equals("")) {
			addFieldError("password1", "请输入确认密码");
		}
		if (!getPassword().equals(getPassword1())) {
			addFieldError("password", "密码和输入密码不一致");
		}
		if (getBirthday() == null) {
			addFieldError("birthday", "请输入生日日期");
		} else if (getBirthday().after(new Date())) {
			addFieldError("birthday", "请不要输入未来日期");
		}
		if (getMobile().length() != 11) {
			addFieldError("mobile", "请输入正确的手机号码");
		}
		if (getAge() < 1 || getAge() > 120) {
			addFieldError("age", "请输入正确年龄");
		}
	}

}


(4).接着配置一下struts.xml文件,成功跳转success.jsp页面,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
        
<struts>
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
	<constant name="struts.devMode" value="true"></constant>
	<package name="input" namespace="/" extends="struts-default">
		<action name="register" class="com.gk.action.RegisterAction">
			<result name="success">/success.jsp</result>
			<result name="input">/register.jsp</result>
		</action>
	</package>
</struts>


(5).接下来附上success.jsp的代码,用来输出注册成功后的信息:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'success.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>

<body>
	用户名为:
	<s:property value="username" />
	<br /> 密码为:
	<s:property value="password1" />
	<br /> 生日为:
	<s:property value="birthday" />
	<br /> 手机号码为:
	<s:property value="mobile" />
	<br /> 年龄为:
	<s:property value="age" />
</body>
</html>


(6).部署此项目到Tomcat服务器上,开启Tomcat服务器,在地址栏输入:http://localhost:8083/InputValidate/register.jsp ,运行效果如下:

不输入任何数据,点击注册按钮,如下图所示:


输入密码不一致时和生日日期不合法时,如下图所示:


(7).对以上代码进行解释:

— Struts2对输入校验这方面采用的最基本的方法是在每个Action里继承ActionSupport类,并且重写它的输入校验方法validate()。上述例子中的RegisterAction代码中显示,根据页面上输入的各种校验将所有不符合输入校验规则的错误信息都由ActionSupport类中另一方法addFieldError方法将错误信息加入到表单错误信息,并且在输入数据的页面显示,而不会再由Action导航到注册成功页面。struts.xml也定义了一个名字为"input"的result,它表明将所有输入失败的错误信息导航到一个特定页面。上述例子将这个特定页面定义为数据输入的页面。

— 再次阅读RegisterAction代码,可以发现在validate方法里编写了很多if语句,每一个if语句中都针对表单中某一字段进行输入校验。如果发现不符合输入校验规则都调用addFieldError方法。该方法中有两个参数,第一个参数都是表单中字段名,这里所有的名字和输入数据的页面中每一个字段的name属性中内容相同。否则Struts2是找不到具体错误信息是针对哪一个字段。这些内容就是在输入校验失败时候显示在之前所说的特定页面中的。

— validate方法中的各个if语句判断了表单中各个字段的输入数据是否符合输入校验的规则,这些规则也是开发人员根据特定业务逻辑定义的。比如其中数据是否输入,输入的生日信息是否在当前日期之前等等。这里又可以发现并没有对这些字段进行类型转换,但在Action中某些字段类型都已经变成Java的一些基本类型。比如生日字段,页面上输入时候是字符串,在Action中已经变成Java中的Date类型。页面上输入的数据已经都由字符串类型转换成Action中指定的Java类型。

— 而输入生日时因为Struts2通过内置的类型转换器进行类型转换,转换失败所以提示Invalid field value for field “birthday”信息。




2.validateXXX方法进行输入校验:这里我们将上面那个InputValidate项目里的一些代码进行修改,看下如何利用validateXXX方法对Action中某一特定的方法进行校验。

(1).首先,修改InputValidate项目的register.jsp页面,只是表单的action属性改为register!register.action,即动态调用action,修改后如下:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'register.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

</head>

<body><s:fielderror></s:fielderror>
	<s:form action="register!register.action" namespace="/">
		<s:textfield name="username" label="用户名"></s:textfield>
		<s:password name="password" label="密码"></s:password>
		<s:password name="password1" label="密码确认"></s:password>
		<s:textfield name="birthday" label="生日"></s:textfield>
		<s:textfield name="mobile" label="手机号码"></s:textfield>
		<s:textfield name="age" label="年龄"></s:textfield>
		<s:submit value="注册"></s:submit>
	</s:form>
</body>
</html>


(2).接着修改一下RegisterAction这个类,里面写了一个方法register和validateRegister方法,其中手机号码那里使用了正则表达式来验证手机号的正确性,修改后代码如下:

package com.gk.action;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

public class RegisterAction extends ActionSupport {
	private String username;
	private String password;
	private String password1;
	private Date birthday;
	private String mobile;
	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 getPassword1() {
		return password1;
	}

	public void setPassword1(String password1) {
		this.password1 = password1;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String register() {
		return SUCCESS;
	}

	public void validateRegister() {
		if (getUsername() == null || getUsername().trim().equals("")) {
			addFieldError("username", "请输入用户名");
		}
		if (getPassword() == null || getPassword().trim().equals("")) {
			addFieldError("password", "请输入密码");
		}
		if (getPassword1() == null || getPassword1().trim().equals("")) {
			addFieldError("password1", "请输入确认密码");
		}
		if (!getPassword().equals(getPassword1())) {
			addFieldError("password", "密码和输入密码不一致");
		}
		if (getBirthday() == null) {
			addFieldError("birthday", "请输入生日日期");
		} else if (getBirthday().after(new Date())) {
			addFieldError("birthday", "请不要输入未来日期");
		}
		if (getMobile().isEmpty()) {
			addFieldError("mobile", "手机号码不为空");
		} else if (!getMobile().matches("\\d*")) {
			addFieldError("mobile", "手机号码错误");
		} else if (getMobile().length() != 11) {
			addFieldError("mobile", "请输入正确的手机号码");
		}
		if (getAge() < 1 || getAge() > 120) {
			addFieldError("age", "请输入正确年龄");
		}
	}
}


(3).其它保持不变,重新部署此项目和开启服务器后,不输入任何数据,点击注册按钮,其地址栏发生变化,如下图:



密码输入不一致和生日类型转换失败,手机号码不正确的话,如下图所示:


(4).对以上代码解释:

— Struts2中除了validate方法之外它还有1种validateXXX方法针对Action中某一特定方法进行该方法的各种字段的输入校验。其中XXX就是该特定方法名。在本示例中定义了一个register方法,该方法和上一小节中的execute方法类似只是一个简单的导航。但是在该registerAction中就没有了validate方法,取而代之的是validateRegister方法。
注意:如果使用validateRegister方法,那最好不要再使用validate方法。虽然和上一小节示例代码比较这两个方法里的内容是完全一摸一样的,但是validate方法是对所有Action中方法的输入校验都进行校验,validateRegister方法只对register方法进行校验。因此两者不能重复使用,都使用会造成两个方法都进行了校验的结果。执行顺序是先validateRegister后validate。如果validateRegister方法有特殊的输入校验则就会被validate方法“覆盖”,因此达不到预期的输入校验目的。
— validateRegister方法中各个if语句定义和上一小节的validate方法内容相同。这里只是作为示例所以两个方法中的内容相同,其实可以和上一小节中的validate方法的内容不相同,用来进行register方法中特定的表单字段输入校验。
— 在数据输入的视图界面又增加了Struts2的标签fielderror。在表单头部也有出错信息显示。这其实和Struts2的校验顺序有关。

在之前说明validateRegister方法和validate方法时候也记述了两者的执行校验顺序是先validateRegister后validate。其实在视图界面进行表单提交后。输入校验顺序是以如下的顺序:
查找Action中是否有validateXXX方法。如果有则执行该方法。将校验产生的错误信息放置到ActionContext对象中。
查找Action中是否有validate方法。如果有则执行该方法。将校验产生的错误信息放置到ActionContext对象中。
查找视图界面是否有fielderror标签定义。如果有则返回到result为“input”的视图。同时ActionContext对象中有关的输入校验的错误信息也显示在该视图中。


Struts2的输入校验顺序就是按照如上说明来先后执行的,这也更好的说明了validateRegister方法和validate方法并存在Action时候输入校验是如何进行的。


(5).修改后的InputValidate项目下载地址:http://download.csdn.net/detail/u012561176/8911561




3.以上内容仅供大家学习参考,写得不好,请见谅,如有错误,请指出,谢谢!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值