1. Struts2的输入校验

1.1 输入校验概述

  输入校验分为客户端校验和服务器端校验,客户端校验主要是过滤正常用户的误操作,主要通过JavaScript代码完成;服务器端校验是整个应用阻止非法数据的最后防线,主要通过在应用中编程实现。

1.1.1 客户端校验

  大多数情况下,使用JavaScript进行客户端校验的步骤如下:

  1. 编写校验函数;
  2. 在提交表单的事件中调用校验函数;
  3. 根据校验函数来判断是否进行表单提交;

  下面通过一个简单的示例讲解使用JavaScript进行客户端校验的方法,具体代码如下所示:

<%--
Created by IntelliJ IDEA.
User: mairr
Date: 17-12-5
Time: 下午10:07
To change this template use File | Settings | File Templates.
--%> <%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page language = "java" import = "java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%> <html>
<head>
<title>注册界面</title>
<script type="text/javascript" > // 去掉前后的空格
function deltrim(x) {
while (x.length > 0 && x.charAt(0) == ' ')
x = x.substring(1, x.length);
while (x.length > 0 && x.charAt(x.length - 1) == ' ')
x = x.substring(0, x.length - 1);
return x;
} // 非空验证
function isNULL(elem,message){
var va = deltrim(elem.value);
if(va == " ") {
alert(message);
elem.focus();
return false;
}
return true;
} // 验证帐号,帐号只能是小写字母数字,并且只能以字母开头
function validateId(){
var first = document.forms[0].id.value.charAt(0);
var exp = /^[a-z0-9]+$/;
if(isNULL(document.forms[0].id,"请输入帐号")){ // 验证非空
// 验证首字符
if((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z')){}
else{
alert("帐号首字符必须是字母!");
document.forms[0].id.focus();
return false;
}
if(!exp.test(document.forms[0].id.value)){
alert("帐号必须是字母或者数字!");
document.forms[0].id.focus();
return false;
}
return true;
}
else{
return false;
}
} // 验证密码,密码要在8位以上,且需要有字母或者数字之外的字符
function validatepwd(){
var exp = /^[a-z0-9]+$/;
if(isNULL(document.forms[0].pwd," 请输入密码")){ //验证非空
if(document.forms[0].pwd.value.length <= 8){
alert("密码大于8位");
document.forms[0].pwd.focus();
return false;
}else{
if(exp.test(document.forms[0].pwd.value)){
alert("密码要有字母和数字之外的字符!");
document.forms[0].pwd.focus();
return false;
}
}
}else{
return false;
}
if(document.forms[0].pwd.value != document.forms[0].repwd.value)
{
alert("两次密码不一样!");
document.forms[0].pwd.focus();
return false;
}
return true;
} // 验证邮箱,右边为六位数子
function checkcode() {
var exp = /^[0-9]+$/;
if(isNULL(document.forms[0].ecode,"请输入邮编")){ // 验证非空
if(document.forms[0].ecode.value.length != 6){
alert("邮编为6位");
document.forms[0].ecode.focus();
return false;
}else{
if(!exp.test(document.forms[0].ecode.value)){
alert("邮编为数字");
document.forms[0].ecode.focus();
return false;
}
}
return true;
}else{
return false;
}
} // 验证E-mail的基本格式
function checkEmail(){
var exp = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
if(isNULL(document.forms[0].email,"请输入Email")){ // 验证非空
if(!exp.test(document.forms[0].email.value)){
alert("Email格式错误");
document.forms[0].email.focus();
return false;
}
return true;
}else{
return false;
}
} // 提交按钮
function gogo(){
if(validateId() && validatepwd() && checkcode() && checkEmail()){
document.forms[0].submit();
return true;
}
return false;
}
</script>
</head>

<body>
<s:form action ="" theme="simple">
<table>
<tr>
<td>登录帐号</td>
<td><s:textfield name="id"/></td>
</tr>
<tr>
<td>密码</td>
<td><s:password name="pwd"/></td>
</tr>
<tr>
<td>确认密码</td>
<td><s:password name="repwd"/></td>
</tr>
<tr>
<td>邮编</td>
<td><s:textfield name = "ecode"/></td>
</tr>
<tr>
<td>Mail</td>
<td><s:textfield name = "email"/></td>
</tr>
<tr>
<td><input type="button" value="提交" onclick="return gogo()" /></td>
<td><s:reset value = "重置"/></td>
</tr>
</table>
</s:form>
</body> </html>

  上述的校验过程中,建立了一个Struts2的项目(前面几篇博文有介绍),JSP校验页面中运用了部分struts2的标签。由上述JSP程序,执行结果有如下几种情况:

  (1) 页面:

  (2) 客户端校验结果:

  客户端校验可以过滤用户的错误操作,是第一道防线,一般使用JavaScript代码实现。仅有客户端校验是不够的。攻击者可以绕过客户端校验直接进行非法输入,这样会引起系统的异常,为了确保数据的合法性,防止用户通过非正常手段提交错误信息,所以必须加上服务器验证。

1.1.2 服务器端校验

  服务器对于系统的安全性、完整性、健壮性起到至关重要的作用。Struts2框架提供了一套验证框架,通过验证框架能够非常简单和快速地完成输入校验。

  在服务器端,对于输入校验Struts2提供了两种实现方法:一是采用手工编写代码实现;另外一种是,给予XML配置方式的实现(校验框架校验)。接下来详细介绍这两种方法。

1.2 手动编程校验

  手动编程校验主要是通过在类中编写校验逻辑代码,有两种方式i:一是在Action类中重写validate()方法;二是在Action类中重写validateXxx()方法。

1.2.1 重写validate方法

  validate()方法会校验Action中所有与execute()方法签名相同的方法。当某个数据校验失败时,在validate()方法中应该调用addFiledError()方法向系统fieldErrors添加校验失败信息。为了使用addFileError方法,Action类需要继承ActionSupport。

  如果系统的fieldErrors包含失败信息,Struts2会将请求转发到名为input的result。在input视图中可以通过<s:fielderror/>标签失败信息。

  下面通过一个简单示例讲解如何重写validate()方法进行输入校验。

(1) 创建一个JSP页面login.jsp,要求验证所有输入项不能为空、密码长度6~12位以及两次密码一样(不运用javascript的客户端校验),具体代码如下所示:

<%--
Created by IntelliJ IDEA.
User: mairr
Date: 17-12-6
Time: 下午9:39
To change this template use File | Settings | File Templates.
--%> <%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %> <%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%> <html>
<head>
<base href="<%=basePath%>">
</head>
<body>
<s:form action="login" theme="simple">
<table>
<tr>
<td>登陆帐号</td>
<td><s:textfield name = "id"/></td>
</tr>
<tr>
<td>密码</td>
<td><s:password name = "pwd"/></td>
</tr>
<tr>
<td>确认密码</td>
<td><s:password name = "repwd"/></td>
</tr>
<tr>
<td><s:submit value= "提交"/></td>
<td><s:reset value = "重置"/></td>
</tr>
</table> <!--显示this.addFieldError("id","id不能为空")的信息-->
<s:fielderror fieldName="id"/> <!--显示所有校验失败信息-->
<s:fielderror/> </s:form>
</body>
</html>

(2) 创建Action类LoginAction.java,在该类中重写validate()方法,具体代码如下“

package action;
import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport {
private String id;
private String pwd;
private String repwd; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getPwd() {
return pwd;
} public void setPwd(String pwd) {
this.pwd = pwd;
} public String getRepwd() {
return repwd;
} public void setRepwd(String repwd) {
this.repwd = repwd;
} // 重写validate方法,进行输入校验,该方法在execute方法之前执行
@Override
public void validate() {
if (id == null || id.trim().equals(" ")) {
this.addFieldError("id", "id不能为空");
}
if (pwd == null || pwd.trim().equals(" ")) {
this.addFieldError("pwd", "密码不能为空");
} else {
if (pwd.length() < 6 || pwd.length() > 12) {
this.addFieldError("pwdlength", "密码的长度在6~12位之间");
}
}
if (!pwd.equals(repwd)) {
this.addFieldError("pwdsame", "两次密码不一致");
}
} // 实现登陆业务处理
@Override
public String execute() {
return SUCCESS;
}
}

(3) 配置Struts2的action,具体代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd"> <struts>
<package name="default" namespace="/" extends="struts-default">
<action name="login" class="action.LoginAction">
<result name="input">/login.jsp</result>
</action>
</package>
</struts>

(4) web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

(5) 运行login.jsp页面,如果输入非法信息则输出校验结果如下所示:

1.2.2 重写validateXxx()方法

  validateXxx()只会校验Action中方法名为Xxx()的方法,其中Xxx的第一个字母要大写。重写validateXxx()方法进行输入校验与重写validate()方法基本一样,唯一不同的就是校验的方法名不同。

  将上面一个例子重写为validateXxx()方法进行输入校验,则需要修改Action类和配置文件。

  • 修改后的Action类的代码如下:
package action;
import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport {
private String id;
private String pwd;
private String repwd; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getPwd() {
return pwd;
} public void setPwd(String pwd) {
this.pwd = pwd;
} public String getRepwd() {
return repwd;
} public void setRepwd(String repwd) {
this.repwd = repwd;
} // 重写validateLogin方法,进行输入校验
public void validateLogin() {
if (id == null || id.trim().equals(" ")) {
this.addFieldError("id", "id不能为空");
}
if (pwd == null || pwd.trim().equals(" ")) {
this.addFieldError("pwd", "密码不能为空");
} else {
if (pwd.length() < 6 || pwd.length() > 12) {
this.addFieldError("pwdlength", "密码的长度在6~12位之间");
}
}
if (!pwd.equals(repwd)) {
this.addFieldError("pwdsame", "两次密码不一致");
}
} // 实现登陆业务处理
public String login() {
return SUCCESS;
}
}
  • 修改后的配置文件struts.xml如下:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd"> <struts>
<package name="default" namespace="/" extends="struts-default">
<action name="login" class="action.LoginAction" method="login">
<result name="input">/login.jsp</result>
</action>
</package>
</struts>
  • 结果是一致的:

1.2.3 输入校验的流程

  经过前面讲解,可以知道,Struts2输入校验需要经过一下几个步骤:

  1. 类型转器对请求参数执行类型转换,并且把转换后的值赋给Action中的属性。
  2. 如果在执行转换过程中出现了异常,系统会把异常信息保存到ActionContext , conversionError拦截器将异常信息添加到fieldError里。不管类型转换是否出现异常,都会进入步骤三;
  3. 系统通过反射技术先调用Action中的validateXxx()方法,Xxx为方法名字。
  4. 再调用Action中的validate()方法;
  5. 经过上面的4个步骤,如果系统中的fieldError存在错误信息(即存放错误信息的集合的size大于0),系统自动将请求转发至名称为input的视图。如果系统中的fileError没有任何错误信息,系统将执行Action中的处理方法。

1.3 校验框架校验

  使用Struts2校验框架的好处是将校验逻辑放到配置文件中,实现校验逻辑代码与业务逻辑代码的分离。使用基于校验框架校验方式实现输入校验时,Action也需要继承ActionSupport,并且提供校验文件。同样框架校验的方式也有2种:一是校验Action中所有与execute方法签名相同的方法;二是校验Action中某个与execute方法签名相同的方法。

1.3.1 Struts2内置的校验器

  Struts2框架提供的内置校验器如下:(多看几遍,还蛮重要的

  1. required:必填校验器,要求field的值不能为null;
  2. requiredstring:必填字符串校验器,要求field的值不能为null,并且长度大于0,默认情况下会对字符串去掉前后空格;
  3. stringlength:字符串长度校验器,要求field的值必须在指定的范围内,否则校验失败;miniLength参数指定最小长度,maxLength参数指定最大长度,trim参数指定校验field之前是否去掉字符串前后空格;
  4. regex:正则表达式校验器,检查被校验的field是否匹配一个正则表达式。expression参数指定正则表达式, caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认值为true;
  5. int:整数校验器,要求field的整数值必须在指定范围内,mini指定最小值,max最大值;
  6. double:双精度浮点数校验器,要求field的双进度浮点数必须在指定范围内,mini指定最小值,max最大值;
  7. fieldexpression:字段OGNL表达式校验器,要求field满足一个OGNL表达式,expression参数指定一个OGNL表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过。该校验器只能用于<filed-validator>;
  8. email:邮件地址校验器,要求如果field的值非空,则必须是合法的邮件地址;
  9. url:网址校验器,要求如果field的值非空,则必须是合法的URL地址i;
  10. date:日期校验器,要求field的日期值必须在指定的范围内,mini指定最小值,max指定最大值;
  11. conversion:转换校验器,指定在类型转换失败时,提示错误信息;
  12. visitor:用于校验Action中的复合属性,指定一个校验文件用于校验复合中的属性;
  13. expression:OGNL表达式表达式校验,expression参数指定OGNL表达式,该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则不通过,该校验器不用在字段校验器的配置中,只能用于<validator>.

1.3.2 常用内置校验器的配置

  

  对于Struts2校验框架来说,一般有两种方式来配置校验器:

  • 使用<validator>
  • 使用<field-validator>

  当<validator>的子节点中配置了<param name="fieldName">用于指定某个属性进行校验时,则达到的效果与<field-validator>是一样的。如下所示:(两种配置方式是等效的

<!--校验user.id属性时,用<validator>来配置-->
<validator type="required">
<s:param name="fieldName">user.id</s:param>
<message>用户的ID不能为空!</message>
</validator> <!--------方式二 ----->
<field name="user.id">
<field-validator type ="required">
<message>用户的ID不能为空!</message>
</field-validator>
</field>

  下面简单介绍几种常用的内置校验器的配置示例:

(1)  required(必填校验器)

<field-validator type ="required">
<message>用户的ID不能为空!</message>
</field-validator>

(2)  requiredstring(必填字符串校验器)

<field-validator type ="requiredstring">
<param name ="trim">true</param>
<message>用户的ID不能为空!</message>
</field-validator>

(3)  stringlength(字符串长度校验器)

<field-validator type ="stringlength">
<param name = "maxlength">12</param>
<param name = "minilength">6</param>
<message>密码必须在6~12位之间</message>
</field-validator>

(4)  email(邮件地址校验器)

<field-validator type ="email">
<message>邮箱格式不正确</message>
</field-validator>

(5)  regex(正则表达式校验器)

<field-validator type ="regex">
<param name="expression"><![CDATA[^1[3578]\d{9}$]]></param>
<message>手机号格式不正确</message>
</field-validator>

(6)  int(整数校验)

<param type ="int">
<param name="max">100</param>
<param name="mini">0</param>
<message>年龄必须在0~100之间</message>
</field-validator>

(7)  字段OGNL表达式校验器

<param type ="int">
<param name="expression"><![CDATA[imagefile.length() <=0 ]]></param>
<message>文件不能为空</message>
</field-validator>

  基于Struts2框架的校验主要是以上内容,这是Struts2框架应用比较多的一个版块,比较重要的内容!

JavaWeb框架_Struts2_(六)----->Struts2的输入校验的更多相关文章

  1. JavaWeb框架_Struts2_(八)----->Struts2的国际化

    这一篇博文拖了蛮久了,现在先把它完成,结束struts2这个版块,当然这只是最基础的部分,做项目还需要更深的理解.下一个web后端的版块准备做Spring框架的学习-嗯,加油! 1. Struts2的 ...

  2. JavaWeb框架_Struts2_(一)----->Struts2 框架入门

    1.  框架入门 2.1  Struts2简介 (1). Struts2是一种基于MVC模式的的轻量级Web开发框架. MVC模式:MVC全名是Model View Controller,是模型(mo ...

  3. JavaWeb框架_Struts2_(五)----->Struts2的标签库

    1.  Struts2的标签库 1.1 Struts2标签库概述 Struts2的标签库可以分为以下3类:用户界面标签.非用户界面标签.AJAX标签; 2.1.1 Struts2标签库的分类和使用 1 ...

  4. JavaWeb框架_Struts2_(二)----->Struts2的核心配置

    2.  Struts2的核心配置 2.1  配置Struts.xml文件 2.1.1 Struts.xml文件 Struts2框架的核心配置文件是Struts.xml,该文件主要用来配置Action和 ...

  5. JavaWeb框架_Struts2_(三)---->Struts2的拦截器

    2. Struts2的拦截器(使用拦截器实现权限控制) 2.1 拦截器的概述 拦截器是Struts2的核心组成部分,它可以动态的拦截Action调用的对象,类似与Servlet中的过滤器.Struts ...

  6. Struts2框架(8)---Struts2的输入校验

    Struts2的输入校验 在我们项目实际开发中在数据校验时,分为两种,一种是前端校验,一种是服务器校验: 客户端校验:主要是通过jsp写js脚本,它的优点很明显,就是输入错误的话提醒比较及时,能够减轻 ...

  7. (十三)struts2的输入校验

    输入校验是web应用必须处理的问题,要防止用户的误输入和恶意非法输入.struts2给我们提供了非常强大的输入校验体系. 输入校验分为客户端校验和服务器端校验.一般开发中两者都用,但是服务端校验必须使 ...

  8. Struts2的输入校验(1)——校验规则文件的编写

    Struts2的输入校验(1) --校验规则文件的编写 Struts2提供了基于验证框架的输入校验,所有的输入校验只要编写配置文件,Struts2的验证框架将会负责进行服务器校验和客户端校验. 注: ...

  9. Struts2的输入校验(2)——客户端校验

    Struts2的输入校验(2) --客户端校验 Struts2客户端校验的使用: (1)使用Struts2的标签生成输入页面的表单: (2)为该<s:form>元素添加validate=& ...

随机推荐

  1. 自学ConcuurentHashMap源码

    自学ConcuurentHashMap源码 参考:https://my.oschina.net/hosee/blog/675884 http://www.cnblogs.com/ITtangtang/ ...

  2. PHP程序员的技术成长之路规划

    按照了解的很多PHP/LNMP程序员的发展轨迹,结合个人经验体会,抽象出很多程序员对未来的迷漫,特别对技术学习的盲目和慌乱,简单梳理了这个每个阶段PHP程序员的技术要求,来帮助很多PHP程序做对照设定 ...

  3. python 生成器和迭代器

    迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个Stoplteration异常,以终止迭代(只能往后走不能往前退) 2.可迭代对象:实现了 ...

  4. Day1作业要求

    Day1作业 作业需求 博客 模拟登录 三级菜单 博客地址 杨振伟Day1博客地址 模拟登录 1.程序说明 实现功能如下 用户输入密码,密码验证后登录成功 用户登录成功后提示登录信息 用户输入3次错误 ...

  5. web前端优化--DOM性能优化

    1.DOM访问与修改的优化: DOM访问是有代价的,修改DOM则会引起DOM的重绘与重排,而这两种操作会消耗性能. (1)缓存DOM:将频繁访问的对象或属性使用变量缓存起来,每次访问的时候,直接使用变 ...

  6. jQuery选择器(基本过滤选择器)第三节

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  7. luogu P1563 玩具谜题

    https://www.luogu.org/problemnew/show/1563 题目: 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩 ...

  8. 【译】Asp.Net Identity Cookies 格式化-中英对照版

    原文出处 Trailmax Tech Max Vasilyev: ASP.Net MVC development in Aberdeen, Scotland I've been reached out ...

  9. OpenCV二维Mat数组(二级指针)在CUDA中的使用

    CUDA用于并行计算非常方便,但是GPU与CPU之间的交互,比如传递参数等相对麻烦一些.在写CUDA核函数的时候形参往往会有很多个,动辄达到10-20个,如果能够在CPU中提前把数据组织好,比如使用二 ...

  10. Nodejs前端服务器压缩图片

    Nodejs作为前端服务器,自然能承担处理图片的能力, 使用GM for nodejs 作为图片处理器,调用ImageMagick处理图片 使用ImageMagick var imageMagick ...