简单的输入校验

servlet硬编码方式进行输入校验:

 

客户端的输入校验:

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
	
<title>请输入您的注册信息</title>
	<meta name="website" content="http://www.crazyit.org" />
	<script type="text/javascript">
	//校验表单的JavaScript函数
	function validate(form)
	{
		//定义错误字符串
		var errStr = "";
		//依次取出表单中的四个表单域的值
		var username = trim(form.username.value);
		var pass = trim(form.pass.value);
		var age = trim(form.age.value);
		var birth = trim(form.birth.value);
		//判断用户名不能为空
		if (username == "" || username == null)
		{
			errStr += "您的用户名必须输入";
		}
		//判断用户名必须是数字和字母,且长度必须为4到25之间
		else if (!/^\w{4,25}$/.test(username))
		{
			errStr += "\n您的用户名必须是字母和数字,且长度在4到25之间";
		}
		//判断密码必须输入
		if (pass == "" || pass == null)
		{
			errStr += "\n您的密码必须输入";
		}
		//判断密码必须是数字和字母,且长度必须为4到25之间
		else if (!/^\w{4,25}$/.test(pass))
		{
			errStr += "\n您的密码必须是字母和数字,且长度在4到25之间";
		}
		//判断年龄必须输入
		if (age == "" || age == null)
		{
			errStr += "\n您的年龄必须输入";
		}
		//判断年龄必须是一个有效的年龄
		else if (!/^[0-1]?[0-9]?[0-9]$/.test(age))
		{
			errStr += "\n您的年龄必须为整数,且必须是一个有效的年龄值";
		}
		//判断生日必须输入
		if (birth == "" || birth == null)
		{
			errStr += "\n您的生日必须输入";
		}
		//判断生日必须是一个有效的日期,且只能是19xx年,或者20xx年
		else if(!/^19\d\d\-[0-1]\d\-[0-3]\d$/.test(birth) 
			&& !/^20[0-1]\d\-[0-1]\d\-[0-3]\d$/.test(birth))
		{
			errStr += "\n您的生日格式不正确,格式:yyyy-MM-DD";
		}
		//如果错误字符串为空,表明客户端校验通过
		if (errStr == "")
		{
			return true;
		}
		//客户端校验没有通过,通过警告框输出校验失败提示
		else
		{
			alert(errStr);
			return false;
		}
	}
	//一个简单的截去字符串前后空格的函数
	function trim(s)
	{
		return s.replace("/^\s*/" , "")
			.replace("/\s*$/" , "")
	}
	</script>

</head>
<body>
<h1>请输入您的注册信息</h1>
<font color="red">
${requestScope.error}
</font>
<form method="post" action="regist"	οnsubmit="return validate(this);">
	用户名:<input type="text" name="username" /><br />
	密  码:<input type="password" name="pass"><br />
	年  龄:<input type="text" name="age"><br />
	生  日:<input type="text" name="birth"><br />
	<input type="submit" value="注册">
</form>

</body>

</html>


上面增加的是客户端的输入校验,如果浏览器输入不符合要求的话,将无法通过校验。但是这仅仅是不能通过该页面的提交请求,攻击者可能用其他的方式提交,可能是使用底层的socket通信。也可以保存源文件,并修改其action来绕过页面校验。

就上面的代码,可以如下修改:

<form action="http://localhost:8888/ClientValidate/regist" method="post">//调用Servlet


这样简单的修改就能绕过页面校验,因此,服务器端的校验就成了最后一道防线。

下面是处理该请求的一个Servlet。

package lee;

import javax.servlet.ServletException;
import javax.servlet.ServletContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.PrintWriter;
import java.io.IOException;

import java.util.*;
import java.text.*;

public class Regist extends HttpServlet
{
	//Servlet的服务响应方法
	public void service(HttpServletRequest request,
		HttpServletResponse response)throws IOException
	{
		//设置解码格式
		request.setCharacterEncoding("GBK");
		//下面4行依次获取4个参数,获取的参数全部为字符串
		String name = request.getParameter("username");
		String pass = request.getParameter("pass");
		String strAge = request.getParameter("age");
		String strBirth = request.getParameter("birth");
		//下面进行类型转换
		//字符串类型向整型转换
		int age = Integer.parseInt(strAge);
		//使用SimpleDateFormat将字符串向日期转换
		//指定转换格式,日期字符串,必须按yyyy-MM-DD的格式输入
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD");
		Date birth = null;
		try
		{
			birth = sdf.parse(strBirth);
		}
		catch (Exception e)
		{
		}
		//将类型转换后值封装成UserBean值对象
		UserBean user = new UserBean(name , pass , age , birth);
		//用Servlet直接输出
		response.setContentType("text/html;charset=GBK");
		//获得页面输出流
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<head>");
		//输出页面标题
		out.println("	<title>类型转换页面</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<h1>类型转换页面</h1>");
		//下面输出值对象user的4个属性值
		out.println("用户的用户名:" + user.getName() + "<br />");
		out.println("用户的密码:" + user.getPass() + "<br />");
		out.println("用户的年龄:" + user.getAge() + "<br />");
		out.println("用户的生日:" + user.getBirth() + "<br />");
		out.println("</body>");
		out.println("</html>");
	}
	public void destroy()
	{
		super.destroy();
	}
}


 

 

Servlet硬编码方式很麻烦,Struts 2提供了基于验证框架的输入校验,在这种方式下,所有的输入校验只需要通过指定简单的配置文件即可。

服务器端:

 

<form method="post" action="regist.action">
	用户名:<input type="text" name="name"><br />
	密  码:<input type="text" name="pass"><br />
	年  龄:<input type="text" name="age"><br />
	生  日:<input type="text" name="birth"><br />
	<input type="submit" value="注册">
</form>


Action:RegistAction.java

public class RegistAction extends ActionSupport
{
	//封装用户请求参数的四个属性
	private String name;
	private String pass;
	private int age;
	private Date birth;

	//name属性的setter和getter方法
	public void setName(String name)
	{
		this.name = name;
	}
	public String getName()
	{
		return this.name;
	}

	//pass属性的setter和getter方法
	public void setPass(String pass)
	{
		this.pass = pass;
	}
	public String getPass()
	{
		return this.pass;
	}

	//age属性的setter和getter方法
	public void setAge(int age)
	{
		this.age = age;
	}
	public int getAge()
	{
		return this.age;
	}

	//birth属性的setter和getter方法
	public void setBirth(Date birth)
	{
		this.birth = birth;
	}
	public Date getBirth()
	{
		return this.birth;
	}

}

校验文件:RegistAction-validation.xml

<?xml version="1.0" encoding="GBK"?>
<!-- 指定校验配置文件的DTD信息 -->
<!DOCTYPE validators PUBLIC
	"-//OpenSymphony Group//XWork Validator 1.0.3//EN"
	"http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
<!-- 校验文件的根元素 -->
<validators>
	<!-- 校验Action的name属性 -->
	<field name="name">
		<!-- 指定name属性必须满足必填规则 -->
		<field-validator type="requiredstring">
			<param name="trim">true</param>
			<message>必须输入名字</message>
		</field-validator>
		<!-- 指定name属性必须匹配正则表达式 -->
		<field-validator type="regex">
			<param name="expression"><![CDATA[(\w{4,25})]]></param>
			<message>您输入的用户名只能是字母和数字
				,且长度必须在4到25之间</message>
		</field-validator>
	</field>
	<!-- 校验Action的pass属性 -->
	<field name="pass">
		<!-- 指定pass属性必须满足必填规则 -->
		<field-validator type="requiredstring">
			<param name="trim">true</param>
			<message>必须输入密码</message>
		</field-validator>
		<!-- 指定pass属性必须满足匹配指定的正则表达式 -->
		<field-validator type="regex">
			<param name="expression"><![CDATA[(\w{4,25})]]></param>
			<message>您输入的密码只能是字母和数字
				,且长度必须在4到25之间</message>
		</field-validator>
	</field>
	<!-- 指定age属性必须在指定范围内-->
	<field name="age">
		<field-validator type="int">
			<param name="min">1</param>
			<param name="max">150</param>
			<message>年龄必须在1到150之间</message>
		</field-validator>
	</field>
	<!-- 指定birth属性必须在指定范围内-->
	<field name="birth">
		<field-validator type="date">
			<!-- 下面指定日期字符串时,必须使用本Locale的日期格式 -->
			<param name="min">1900-01-01</param>
			<param name="max">2050-02-21</param>
			<message>生日必须在${min}到${max}之间</message>
		</field-validator>
	</field>
</validators>



 Struts 2的校验文件规则和Struts 1的校验文件设计方式不同,Struts 2中每一个Action都有一个校验文件,因此该文件的文件名应该遵守如下规则:

<Action名字>-validation.xml

校验文件放在action的文件夹里。

在Struts.xml中有定义input视图,当有错误时,会将错误提示信息发给<s:fielderror/>显示

 

……
<message>${getText("name.regex")}</message>
……
<message>${getText("pass.requried")}</message>
……


 

客户端的输入校验:

 增加客户端校验非常简单,将输入界面的表单元素改为使用Struts 2标签生成表单,并且为该表单增加 validate="true"  属性即可。

regist.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>请输入您的注册信息</title>
<meta name="website" content="http://www.crazyit.org" />
<s:head/>
</head>
<body>
<h3>请输入您的注册信息</h3>
<!-- 使用Struts 2标签库生成表单 -->
<s:form action="regist" validate="true">
	<!-- 使用s:textfield标签生成文本输入框 -->
	<s:textfield label="用户名" name="name"/>
	<s:password label="密码" name="pass"/>
	<s:textfield label="年龄" name="age"/>
	<s:textfield label="生日" name="birth"/>
	<s:submit/>
</s:form>
</body>
</html>


 action同服务器端一样

像之前的错误提示信息都是写在配置文件中的,这样不利于国际化的提示信息。为了国际化提示信息,为message元素指定key属性,该属性指定是国际化提示信息对应的key。

服务器端的使用方法:

……
<message key=“name.requried”/>
……
<message key=“pass.requried”/>
……

 

 客户端使用方法:

……
<message>${getText("name.requried")}</message>
……
<message>${getText("pass.requried")}</message>
……


因为上面的校验文件指定了很多国际化信息的key,所以必须在国际化资源文件中增加对应的key。

globalMessage.properties

xwork.default.invalid.fieldvalue={0}字段无效
#违反用户名必须输入的提示信息
name.requried=您必须输入用户名!
#违反用户名必须匹配正则表达式的提示信息
name.regex=您输入的用户名只能是字母和数字,且长度必须在4到25之间!
#违反密码必须输入的提示信息
pass.requried=您必须输入密码!
#违反密码必须匹配正则表达式的提示信息
pass.regex=您输入的密码只能是字母和数字,且长度必须在4到25之间!
#违反年龄必须在指定范围的提示信息
age.range=您的年龄必须在1和150之间!
#违反生日必须在指定范围的提示信息
birth.range=您的生日必须在1900-01-0和2050-02-21之间!


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值