前言

  这个本来是昨天就写好的,但是不知道为什么没有保存成功!但是今天起来再写一遍就当巩固一下知识吧。

一、输入校验概述

  在以前我们写一个登录页面时,并没有限制用户的输入,不管用户输入什么,我们都存入数据库中,很显然这是不行的,我们需要检测用户输入的文本是否合法,

  是否符合我们需要的文本格式,符合就放行,而struts2中就有这种功能,能帮我们在服务器段进行判断,比如用户名不能为空,年龄只能在0-100之间等。现在

  我们就来说说如何使用struts2中的校验功能把。

  分为两种:编程式校验和配置校验(XML配置校验)

1)验证方式

  客户端验证:javascript

  服务端验证:逻辑验证

  注意:如果客户端和服务端验证二选一,服务端必不可少。用户的输入验证,必须做,且工作量巨大。

  实际开发中:服务端+客户端都需要验证

2)struts2的服务验证

  在struts2的框架中,它也提供了一个Map<表单的字段名,错误提示>,我们要做的:往map中存放错误信息。

二、编程式校验

2.1、前提条件

  前提:动作类必须继承ActionSupport  

      重写validate方法

  注意:

     1)validate方法会在动作方法执行之前,进行验证。

     2)实现Validateable接口,重写其中的validate方法,因为我们的action继承自actionSupport,actionsupport帮我们实现了这接口,

       所以我们只需要重写validate方法即可。

2.2、细说编程式校验

  

  在这里使用了一个addFieldError("xxx","yyy"); 将错误信息存起来,等回到页面在显示出来,如何显示呢?

  如果使用的是s标签提交的表单,那么该会自动显示出来,如果不是,则需要手动将其输出,<s:fielderror fieldName="xxx">.。并且如果使用了,addFieldError中存有了信息,

  则不会在前往原先action所需要跳转的页面,而是找到result为input的结果码对应的页面。所以,如果需要使用它,那么在struts.xml中应该编写一个结果码为input的代码。

  为什么需要input结果码等?原因是这种输入校验依靠了两个拦截器,如图所示:

    

  这种数据检验都是在数据进行类型转换之后做的事情,从图中的几个拦截器就可以看先后执行顺序,也可以解释为什么需要input结果码了。

  对单个方法或指定方法进行数据校验。

  上面这种对所有方法校验有些不符合我们的要求,因为并不是每个方法都需要提交表单参数过来的,所以struts2中有两种办法解决这个问题:

    1)还是对所有方法进行校验,不过可以将我们不需要使用校验的方法上用注解@SkipValidation进行跳过即可。

    2)指定校验某个方法, 比如validateAdd()这就只校验add方法, validateLogin() 值校验login方法,以这样的格式进行命名,就是对特定方法进行校验了。

  注意:指定某个方法校验会在公共校验方法之前被调用,也就是说会先执行validateXXX(),然后在执行validate()方法。

2.3、编程式校验之demo

  1)在动作类UserAction中继承AcctionSupport,重写Validate方法

    

    备注:StringUtils是struts框架中org.apache.commons.lang3.StringUtils,jar包中的,增强了String的功能。

    

  2)register.jsp

    

  3)配置struts.xml文件

    

  4)测试(没有输入用户名直接按注册)

    

  问题:当重写了validate方法,它会对动作类中的所用动作方法进行验证。

    举例:

    

    在UserAction中添加动作方法

    

    testValidate.jsp

    

    最后创建一个index.jsp用来测试

    

    结果:

    

    当我们注释掉Validate方法时:

   

  解决验证所有动作方法的问题:   

    第一种方式:
      使用@SkipValidation的注解

      就是我们不需要去验证testValidate方法我们就在定义方法的上面进行注释
     第二种方式:
       定义验证方法的名称:validate+动作名称 动作名称的首字符还要大写

  public void validateRegister(){
if(StringUtils.isEmpty(user.getUsername())){
//存入错误信息,直接调用父类的addFieldError方法,存入错误信息。第一个参数是表单name属性的值。第二个参数是错误提示
addFieldError("username", "请输入用户名");
}

  编程式验证弊端:硬编码

三、XML校验

  通过编写验证规则的xml文件。需要验证时,编写xml文件,不要验证,就不要写。

  优点:解决了编程式验证的弊端

3.1、前提条件

  1)必须实现validateable接口,actionsupport已经实现了,所以我们只需要直接继承actionsupport即可 

  2)action中必须为属性提供getXXX、setXXX方法,因为代码校验是在Action本类中来完成校验,这说明我们可以直接使用本类的private属性,但如果使用

    XML配置方式校验,这需要使用校验框架的代码来完成校验工作,那么校验框架需要调用Action的getXXX()方法来获取被校验的属性,所以一定要为被

    校验的属性提供getXXX()方法。

3.2、创建校验配置文件

  1)命名规范

    actionClass-actionName-validation.xml  

       actionClass:action的类名

       actionName:action的访问名称,及在struts.xml中配置的,<action name="">

       validation.xml:固定后缀名。 

    比如:Demo02Action-Demo02Action_add-validation.xml    这种是对特定方法进行校验

  2)路径

    必须与action同包下

    

3.3、编写校验文件

  校验文件的DTD:在xwork-core-x.x.x.jar中找到xwork-validator-x.x.x.dtd,打开它,内部会有一段DTD,我们把它copy过来,放到我们的校验文件中。    

  

  1)内置校验器

    Struts内置的常用声明式验证器位置:

      在xwork-core-xxx.jar/com.opensymphony.xwork2/validator/validators/default.xml中就能够找到所有的校验规则。

      我的在

    

    详解:

    

  2)如何使用校验器

    如果想要查看某个校验规则如何使用的话,看源码,然后打开Javadoc进行查看,其中会有例子让我们查看的。比如,我需要查看requiredstring的使用方法。

    复制requiredstring的class:

      

    按shift+ctrl+t对该类进行查找:

      

    查看文档:

      

3.4、针对动作类的所有动作进行验证

  在动作类所在的包中,建立一个ActionClassName-validation.xml的文件 

  

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<!-- 当使用ActionClassName-validation.xml来命名文件时,它是一个动作类验证器。会验证动作类中的所有动作方法 -->
<validators>
<!-- 基于字段的声明式验证 -->
<!-- field中name属性指定的是表单name属性的取值 -->
<field name="username">
<!-- struts2框架为我们集成了很多的内置验证器。requiredstring会验证输入内容是否为空,是否为空字符串。并且去掉左右空格-->
<field-validator type="requiredstring">
<message>请输入用户名</message>
</field-validator>
</field>
</validators>

  这是一个会验证所有动作方法的,又回到了我们上面编程式验证所遇到的问题。那我们怎么去解决呢?

    解决一:使用@SkipValidation的注解

    解决二:定义一个针对验证动作类中某个动作方法的xml  

3.5、.针对动作类中的某个动作进行验证

  在动作类所在的包中建立一个xml文件,名称为ActionClassName-ActionName-validaton.xml的文件

  内容和上面的一样,只是修改一下名称。

  测试:

  

3.6、基于验证器的验证

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<!-- 当使用ActionClassName-ActionName-validation.xml来命名文件时,它是一个指定动作方法的验证器。只会验证指定的动作方法 -->
<validators>
<field name="username">
<field-validator type="requiredstring">
<message>请输入用户名必须要输入</message>
</field-validator>
</field> <!-- 基于验证器的验证 -->
<validator type="requiredstring">
<!-- 以注入的方式,提供要验证的字段信息
setFieldName("password");
-->
<param name="fieldName">password</param>
<message>密码必须输入</message>
</validator>
</validators>

  为什么param中的name是filedName呢?

  1)我们可以查看一下源码:

       

  2)查看的源码

  3)查找父类

    

  4)查看源码

    

四、基于XML验证的实例

  1)编写一个Student.java

package com.jxlg.domain;

import java.io.Serializable;
/**
* URL:uniform resource locator 统一资源定位符
* http://localhost:6060/studentManagement/home.jsp
* 协议 主机 端口 URI
* URI:uniform resource identifier 统一资源标识符
* studentManagement/home.jsp
* @author Shinelon
*
*/
public class Student implements Serializable {
private String username;//不能为null和空字符串。要去空格
private int age;//整数,介于18-100之间
private String email;//按照邮箱的格式输入
private String password;//密码。长度3-8位
private String repassword;//确认密码,必须和密码一致。写在这里的目的,完全是为了演示验证器的使用。实际开发中根本不会保存确认密码。
private int score;//成绩,必须是自然数
private String url;//个人主页:必须符合url格式
private String gender;//性别
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRepassword() {
return repassword;
}
public void setRepassword(String repassword) {
this.repassword = repassword;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
} }

Student

  2)编写一个student.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<s:actionerror/>
<%-- <s:fielderror />字段错误
动作错误 --%>
<%--struts2的form标签,它提供了和原始html表单标签几乎一致的属性
action:请求地址。直接写动作名称。不用写contextPath
method:请求方式。在这里可以不写,struts的form表单中默认是post
enctype:表单编码的MIME类型 --%> <s:form action="addStudent.action">
<s:textfield name="username" label="用户名" />
<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="url" label="个人主页"/>
<%--list中的取值是生成一个list集合,并往集合中放入元素 --%>
<s:radio name="gender" list="{'男','女'}" label="性别"/>
<s:submit value="注册"/>
</s:form>
</body>
</html>

student.jsp

  3)编写一个struts.xml,配置addStudent.action

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true"></constant>
<package name="p1" extends="struts-default"> <!-- 声明式验证器的案例的动作类配置 -->
<action name="addStudent" class="com.jxlg.web.action.StudentAction" method="addStudent">
<result name="input">/student.jsp</result>
</action>
</package>
</struts>

struts.xml

  4)编写StudentAction动作类继承ActionSupport类和实现modelDriven接口

package com.jxlg.web.action;

import com.jxlg.domain.Student;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven; public class StudentAction extends ActionSupport implements ModelDriven<Student> { private Student stu = new Student();
public Student getModel() {
return stu;
} public String addStudent(){
return SUCCESS;
}
public Student getStu() {
return stu;
}
public void setStu(Student stu) {
this.stu = stu;
} }

StudentAction

  5)编写UserAction-register-validation.xml来配置验证器

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-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"></param>
<param name="max"></param>
<message>请输入18-100之间的整数</message>
</field-validator>
</field>
<field name="email">
<field-validator type="email">
<message>请输入正确的邮箱格式</message>
</field-validator>
</field>
<field name="password">
<field-validator type="requiredstring">
<!-- 注入取消使用trim -->
<param name="trim">false</param>
<message>请输入密码</message>
</field-validator>
<field-validator type="stringlength">
<param name="minLength"></param>
<param name="maxLength"></param>
<message>请输入3-8位的密码</message>
</field-validator>
</field> <!-- 确认密码和密码必须保持一致,是2个字段的事情,所以要使用基于验证器的声明方式 -->
<validator type="expression">
<param name="expression">
<!-- CDATA为了去掉特殊字符 -->
<![CDATA[
password == repassword
]]>
</param>
<message>两次密码必须一致</message>
</validator>
<field name="score">
<field-validator type="regex">
<param name="regex">
/d+
</param>
<message>请正确输入成绩</message>
</field-validator>
</field>
<field name="url">
<field-validator type="url">
<message>请正确输入url</message>
</field-validator>
</field>
<field name="gender">
<field-validator type="required">
<!-- required是一个只验证是否为null的内置验证器,不去除空格 -->
<message>请输入性别</message>
</field-validator>
</field>
</validators>

UserAction-register-validation.xml

  6)测试

    

  开发中的问题:

    1)在测试自己的student.jsp的页面中出现了错误  

      

      经过查看自己的score的标签中的name没有写导致的错误

    2)在测试密码和确认密码的时候发现不一致也不报错

      

      它属于动作错误,所以需要写上面的标签

      

 喜欢就推荐哦!

struts2(四)之输入校验的更多相关文章

  1. struts2框架之输入校验(参考第二天学习笔记)

    输入校验: 1. 分类 客户端校验:javascript,它是用户体验而已,可以绕开. 服务器端校验 * 代码校验 1). 要求Action必须继承ActionSupport 2). 重写Action ...

  2. [Struts2学习笔记] -- 输入校验

    Struts2可以对客户端的输入进行校验,通过重写ActionSupport的validate方法来实现,具体如下: 首先通过用struts标签库创建一个form表单,表单中控件的name与actio ...

  3. Struts2 输入校验 第四弹

    ActionSupport 里面有一个validate.可以重写里面你的方法. 校验执行流程: 1)首先进行类型转化 2)然后进行输入校验(执行validate方法) 3)如果在上述过程中出现了任何错 ...

  4. Struts2的输入校验

    一.Struts2提供了基于验证框架的输入校验,在这种校验方式下,所有的输入校验只需要编写简单的配置文件,Struts2的验证框架将会负责进行服务器校验和客户端校验. 校验失败后将Struts2将自动 ...

  5. 【Struts2学习笔记(11)】对action的输入校验和XML配置方式实现对action的全部方法进行输入校验

    在struts2中,我们能够实现对action的全部方法进行校验或者对action的指定方法进行校验. 对于输入校验struts2提供了两种实现方法: 1. 採用手工编写代码实现. 2. 基于XML配 ...

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

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

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

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

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

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

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

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

随机推荐

  1. Flask-WTF CSRF 保护P3

    使用FlaskForm处理请求的任何视图函数都已经获得了CSRF保护.如果有些视图函数还在使用FlaskForm或AJAX请求,请尽快使用FlaskForm提供的CSRF扩展来保护它们. 导入 想要为 ...

  2. angular学习笔记02 angular指令大全

    第一步 先要引入angular, 第二步  在 html 标签中<html  ng-app>  加入ng-app(这是个必须的,不然会报错) 接下来就可以去使用angular的各种指令了. ...

  3. php调用webservice接口

    项目中使用到了调用三方厂商webService接口.他的接口类似为http://haha.cn:86/BaseInfoService.svc?wsdl,在这里我注意到了"wsdl" ...

  4. Struts2的核心运行流程,原理图解

    感觉很有必要制定一个计划,这样盲目的想到哪里写到哪里,不符合我大程序员的思维逻辑呀~~~嗯...那就从基本的开始吧,循循渐进,今天想到的先写上,不能浪费了,哈哈哈................... ...

  5. 小符号反映大问题,Shell中下划线_与变量的关系。

    之前写过一个根据日期和时间自动命名文件名的时候遇到一个问题. #! /bin/bash read -p "please input the filename:" filename ...

  6. 宝藏(树形DP)

      这道题目是十分考验思维的,n^2应该还是比较好想的,主要是如何转移根的问题.转移根,在我看来应该是树形dp最难的一部分了, 一般学会如何转移根,也就差不多考验通吃树形dp了. 下面转一转大佬链接: ...

  7. 【Learning】多项式乘法与快速傅里叶变换(FFT)

    简介: FFT主要运用于快速卷积,其中一个例子就是如何将两个多项式相乘,或者高精度乘高精度的操作. 显然暴搞是$O(n^2)$的复杂度,然而FFT可以将其将为$O(n lg n)$. 这看起来十分玄学 ...

  8. Request.QueryString("id")与Request("id")区别

    Request从几个集合取数据是有顺序的,从前到后的顺序依次是 QueryString,Form,最后是ServerVariables.Request对象按照这样的顺序依次搜索这几个集合中的变量,如果 ...

  9. HDU2036 改革春风吹满地

    第一次看到这题果断放弃,毕竟几何白痴,第二次刷没做的题的时候突然想到这个三角形面积的向量法:S=|x1*y2-x2*y1|  但是此题可能是凹多边形,所以不能加绝对值,可以画个凹四边形看看. HDU2 ...

  10. Win10系统下安装Ubuntu16.04.3教程与设置

    在Win10上刚刚装好Ubuntu16.04.3,装了不下于10次,期间出现很多问题,趁着还有记忆,写下这篇教程,里面还有Ubuntu系统的优化与Win10的一些设置. Part 1 制作Ubuntu ...