`

在Struts 2_0中实现表单数据校验

 
阅读更多

转换与校验(Conversion & Validation)

其实上篇文章,我本来是打算写表单数据校验的内容,但是经过再三思考后,还是决定先写Struts 2.0转换器的内容。原因是我认为转换是校验的基础,只有在数据被正确地转换成其对应的类型后,我们才可以对其取值范围进行校验。看个例子相信大家可以更清楚。现在我们就来改造一下《转换器(Converter)——Struts 2.0中的魔术师》的第一个例子。

首先,从Action开始,修改后的代码如下:

package tutorial;

import java.util.Locale;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.LocalizedTextUtil;

public class HelloWorld extends ActionSupport {
   
private String msg;
   
private Locale loc = Locale.US;
   
   
public String getMsg() {
       
return msg;        
   }

   
   
public Locale getLoc() {
       
return loc;
   }

   
   
public void setLoc(Locale loc) {
       
this .loc = loc;
   }

   
   @Override
   
public void validate() {
       System.out.println(
" Calling validate() " );
       
if ( ! (loc.equals(Locale.US) || loc.equals(Locale.CHINA))) {
                   addFieldError(
" loc " , getText( " validation.loc " ));
       }

   }

       
   
public void validateExecute() {
       System.out.println(
" Calling validateExecute() by reflection " );
   }

   
   @Override
   
public String execute() {
       System.out.println(
" Calling execute() " );
       
// LocalizedTextUtil是Struts 2.0中国际化的工具类,<s:text>标志就是通过调用它实现国际化的
           msg = LocalizedTextUtil.findDefaultText( " HelloWorld " , loc);
       
return SUCCESS;
   }

}

然后,修改Struts.xml中Action的定义指明输入地址:

< action name ="HelloWorld" class ="tutorial.HelloWorld" >
   
< result > /HelloWorld.jsp </ result >
   
< result name ="input" > /HelloWorld.jsp </ result >
</ action >

接着,在HelloWorld.jsp中加入错误提示:

<% @ page  contentType = " text/html; charset=UTF-8 " %>
<% @taglib prefix = " s " uri = " /struts-tags " %>
< html >
< head >
   
< title > Hello World </ title >
</ head >
< body >
   
< div style ="color:red;" >
       
< s:fielderror />
   
</ div >
   
< s:form action ="HelloWorld" theme ="simple" >            
        Locale:
< s:textfield name ="loc" /> &nbsp; < s:submit />
   
</ s:form >    
   
< h2 >< s:property value ="msg" /></ h2 >
</ body >
</ html >

再修改LocaleConverter.java文件,将内容改为:

package tutorial;

import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;

public class LocaleConverter extends ognl.DefaultTypeConverter {
   @Override
   
public Object convertValue(Map context, Object value, Class toType) {
       
if (toType == Locale. class ) {            
           System.out.println(
" Converting String to Locale " );
           String locale
= ((String[]) value)[ 0 ];
           
return new Locale(locale.substring( 0 , 2 ), locale.substring( 3 ));
       }
else if (toType == String. class ) {
           System.out.println(
" Converting Locale to String " );
           Locale locale
= (Locale) value;
           
return locale.toString();
       }

       
return null ;
   }

}

之后,修改国际化资源文件,内容为:

HelloWorld = 你好,世界!
invalid.fieldvalue.loc
= Locale必须为\ " xx_XX\ " 的格式
validation.loc
= 区域必须为中国或美国

globalMessages_zh_CN.properties

HelloWorld = Hello World!
invalid.fieldvalue.loc
= Locale must like \ " xx_XX\ "
validation.loc
= Locale must be China or USA

globalMessages_en_US.properties

发布运行应用程序,在浏览器中键入http://localhost:8080/Struts2_Validation/HelloWorld.action,在Locale中输入zh_CN,按“Submit”提交,效果如上篇文章所示。而在服务器控制台有如下输出:

Converting String to Locale...
Calling validateExecute() by reflection...
Calling validate()...
Calling execute()...
Converting Locale to String...

上述的输出说明了Struts 2.0的数据校验工作方式,它需要经过下面几个步骤:

  1. 通过转换器将请求参数转换成相应的Bean属性;
  2. 判断转换过程是否出现异常。如果有,则将其保存到ActionContext中,conversionError拦截器再封装为fieldError;如果没有,进行下一步;
  3. 通过反射(Reflection)来调用validateXxx()方法(其中,Xxx表示Action的方法名);
  4. 调用validate()方法;
  5. 如果经过上述步骤没有出现fieldError,则调用Action方法;如果有,则会跳过Action方法,通过国际化将fieldError输出到页面。

不喜欢看文字的朋友,可以参考下面的图1。

图1 校验顺序图
图1 校验顺序图

看到这里可能大家会疑问:“这么多地方可以校验表单数据,到底我应该在那里做呢?”有选择是好事,但抉择的过程往往是痛苦的,往往让人不知所措。如果大家参照以下几点建议,相信会比较容易地做出正确的抉择。

  1. 如果需要转换的数据,通常做法在转换的时候做格式的校验,在Action中的校验方法中校验取值。假如用户填错了格式,我们可以通过在资源文件配置invalid.fieldvalue.xxx(xxx为属性名)来提示用户正确的格式,不同的阶段出错显示不同的信息。具体做法请参考上面的例子;
  2. 至于用validate()还是validateXxx(),我推荐使用validate()。原因是validateXxx()使用了反射,相对来说性能稍差,而validate()则是通过接口com.opensymphony.xwork2.Validateable调用。当然如果你的表单数据取值是取决于特定Action方法,则应该使用validateXxx()。

在运行上面的例子时,在Locale中输入zh并提交时出现图2所示页面。

图2 错误格式
图2 错误格式

在Locale中输入de_DE时,出现如图3所示页面。

图3 取值错误
图3 取值错误

使用Struts 2.0的校验框架

上一节的内容都是关于如何编程实现校验,这部分工作大都是单调的重复。更多情况下,我们使用Struts 2.0的校验框架,通过配置实现一些常见的校验。

我学习编程有个习惯——喜欢先看输出结果,再看代码实现。这样学的好处是先看结果可以刺激学习的激情,也可以在看代码前自已思考一下如何实现,然后带着问题去看代码,那就清晰多了。因此下面我们先来做演示。

首先,在tutorial包下新建ValidationAction.java,代码如下:

package tutorial;

import com.opensymphony.xwork2.ActionSupport;

public class ValidationAction extends ActionSupport {
   
private String reqiuredString;

   
public String getReqiuredString() {
       
return reqiuredString;
   }


   
public void setReqiuredString(String reqiuredString) {
       
this .reqiuredString = reqiuredString;
   }

   
   @Override
   
public String execute() {
       
return SUCCESS;
   }
   
}

然后,配置上述所建的Ation,代码片段如下:

< action name ="ValidationAction" class ="tutorial.ValidationAction" >
   
< result > /Output.jsp </ result >
   
< result name ="input" > /Input.jsp </ result >
</ action >

接着,创建Input.jsp和Output.jsp,内容分别如下:

<% @ page  contentType = " text/html; charset=UTF-8 " %>
<% @taglib prefix = " s " uri = " /struts-tags " %>
< html >
< head >
   
< title > Hello World </ title >
   
<!-- 此标志的作用是引入Struts 2.0的常用的Javascript和CSS -->
   
< s:head />
</ head >
< body >
   
< s:form action ="ValidationAction" >            
       
< s:textfield name ="reqiuredString" label ="Required String" />
       
< s:submit />
   
</ s:form >    
</ body >
</ html >

Input.jsp

<% @ page  contentType = " text/html; charset=UTF-8 " %>
<% @taglib prefix = " s " uri = " /struts-tags " %>
< html >
< head >
   
< title > Hello World </ title >
</ head >
< body >
    Required String:
< s:property value ="reqiuredString" />    
</ body >
</ html >

Output.jsp

再接下来,在tutorial包下创建ValidationAction的校验配置文件Xxx-validation.xml(Xxx为Action的类名),在本例中该文件名ValidationAction-validation.xml,内容如下:

<? xml version="1.0" encoding="UTF-8" ?>
<! DOCTYPE validators PUBLIC 
          "-//OpenSymphony Group//XWork Validator 1.0//EN" 
          "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"
>          
< validators >
   
< field name ="reqiuredString" >
       
< field-validator type ="requiredstring" >
           
< message > This string is required </ message >
       
</ field-validator >
   
</ field >
</ validators >

发布运行应用程序,在地址栏中键入http://localhost:8080/Struts2_Validation/Input.jsp,出现如图4所示页面。

图4 Input.jsp
图4 Input.jsp

直接点击“Submit”提交表单,出现图5所示的页面。

图5 错误提示
图5 错误提示

在Required String中随便填点东西,转到Output.jsp页面,如图6所示。

图6 Output.jsp
图6 Output.jsp

通过上面的例子,大家可以看到使用该校验框架十分简单方便。不过,上例还有两点不足:

  1. 还没有国际化错误消息;
  2. 没有实现客户端的校验。

当然,要完善以上不足,对于Struts 2.0来说,只是小菜一碟。

  1. 在Xxx-validation.xml文件中的<message>元素中加入key属性;
  2. 在Input.jsp中的<s:form>标志中加入validate="true"属性,就可以在用Javascript在客户端校验数据。

下面是具体的实现,首先在国际化资源文件中加入错误消息,然后按照上面说明实现。因为要使用Javascript在客户端显示出错信息,所以在加载Input.jsp页面时,Struts 2.0需要获得国际化的字符串,故我们需要使用Action来访问Input.jsp页面,具体实现请参考《在Struts 2.0中国际化(i18n)您的应用程序》的最后部分。最后发布运行应用程序,直接在页面中点击“Submit”,表单没有被提交并出现错误提示,如图7所示:

图7 客户端校验
图7 客户端校验

校验框架是通过validation拦截器实现,该拦载被注册到默认的拦截器链中。它在conversionError拦截器之后,在validateXxx()之前被调用。这里又出现了一个选择的问题:到底是应该在action中通过validateXxx()或validate()实现校验,还是使用validation拦截器?绝大多数情况,我建议大家使用校验框架,只有当框架满足不了您的要求才自已编写代码实现。

配置文件查找顺序

在上面的例子中,我们通过创建ValidationAction-validation.xml来配置表单校验。Struts 2.0的校验框架自动会读取该文件,但这样就会引出一个问题——如果我的Action继承其它的Action类,而这两个Action类都需要对表单数据进行校验,那我是否会在子类的配置文件(Xxx-validation.xml)中复制父类的配置吗?

答案是不,因为Struts 2.0的校验框架跟《在Struts 2.0中国际化(i18n)您的应用程序》提到的“资源文件查找顺序”相似,有特定的配置文件查找顺序。不同的是校验框架按照自上而下的顺序在类层次查找配置文件。假设以下条件成立:

  1. 接口 Animal;
  2. 接口 Quadraped 扩展了 Animal;
  3. 类 AnimalImpl 实现了 Animal;
  4. 类 QuadrapedImpl 扩展了 AnimalImpl 实现了 Quadraped;
  5. 类 Dog 扩展了 QuadrapedImpl;

如果Dog要被校验,框架方法会查找下面的配置文件(其中别名是Action在struts.xml中定义的别名):

  1. Animal-validation.xml
  2. Animal-别名-validation.xml
  3. AnimalImpl-validation.xml
  4. AnimalImpl-别名-validation.xml
  5. Quadraped-validation.xml
  6. Quadraped-别名-validation.xml
  7. QuadrapedImpl-validation.xml
  8. QuadrapedImpl-别名-validation.xml
  9. Dog-validation.xml
  10. Dog-别名-validation.xml

已有的校验器

Struts 2.0已经为您实现很多常用的校验了,以下在jar的default.xml中的注册的校验器。

< validators >
   
< validator name ="required" class ="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator" />
   
< validator name ="requiredstring" class ="com.opensymphony.xwork2.validator.validators.RequiredStringValidator" />
   
< validator name ="int" class ="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator" />
   
< validator name ="double" class ="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator" />
   
< validator name ="date" class ="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator" />
   
< validator name ="expression" class ="com.opensymphony.xwork2.validator.validators.ExpressionValidator" />
   
< validator name ="fieldexpression" class ="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator" />
   
< validator name ="email" class ="com.opensymphony.xwork2.validator.validators.EmailValidator" />
   
< validator name ="url" class ="com.opensymphony.xwork2.validator.validators.URLValidator" />
   
< validator name ="visitor" class ="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator" />
   
< validator name ="conversion" class ="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator" />
   
< validator name ="stringlength" class ="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator" />
   
< validator name ="regex" class ="com.opensymphony.xwork2.validator.validators.RegexFieldValidator" />
</ validators >

总结

使用校验框架既可以方便地实现表单数据校验,又能够将校验与Action分离,故我们应该尽可能使用校验框架。在使用校验框架时,请不要忘记通过在资源文件加入invalid.fieldvalue.xxx字符串,显示适合的类型转换出错信息;或者使用conversion校验器。

分享到:
评论

相关推荐

    struts2中文学习资料

    "在Struts 2_0中实现表单数据校验(Validation)" 介绍了Struts2的内置数据校验机制,这包括编写校验规则,使用FieldError处理错误,以及如何在视图层显示这些错误。 4. **转换器(Converter)**: "转换器...

    struts2[1].0标签详解

    Struts 2的基石——拦截器(Interceptor);在Struts 2_0中国际化(i18n)您的应用程序;在Struts 2_0中实现表单数据校验(Validation);Struts 2与AJAX;在Struts 2中实现IoC......

    在Struts 2.0中实现表单数据校验

    ### 在Struts 2.0中实现表单数据校验 #### 一、引言 在Web应用开发中,确保用户提交的数据有效性和安全性是非常重要的一步。Struts 2.0框架提供了强大的功能来帮助开发者处理这些任务。本文将详细介绍如何在Struts...

    Struts2_CRUD.rar_Struts2_CRUD_Struts2的增改删查 操作 示例_struts2_struts2

    综上所述,"Struts2_CRUD"示例涵盖了使用Struts2框架进行基本数据操作的核心概念和实践。通过学习这个示例,初学者可以理解如何在Struts2中组织Action、Form、Interceptor、配置文件和视图,以及如何实现CRUD操作和...

    struts2 简单数据校验

    在“Struts2_1100_SimpleDataValiation”这个压缩包中,可能包含了相关的代码示例、教程文档,或者是一个简单的Struts2项目,用于演示如何在实际应用中实现数据校验。你可以通过解压文件,学习和理解Struts2数据校验...

    struts2_OGNL Demo

    Struts2_OGNL Demo 是一个用于演示Struts2框架中OGNL(Object-Graph Navigation Language)表达式语言的实例。这个项目旨在帮助开发者理解和学习如何在Struts2中使用OGNL来操纵对象和数据。OGNL是Struts2中一个重要的...

    Struts2 校验器

    在Struts2中,校验器(Validator)是处理用户输入验证的核心组件,确保提交到服务器的数据符合预设的业务规则。这篇博客文章可能是关于如何使用Struts2的内置校验机制以及自定义校验规则的探讨。 Struts2的校验框架...

    struts2的数据校验

    在Struts2中,数据校验是一项至关重要的功能,它确保了用户提交的数据符合预定义的规则和格式,从而提高应用的安全性和数据质量。下面我们将详细探讨Struts2中的数据校验机制。 首先,数据校验是Web应用开发中的...

    Struts2_0100_Hell0

    在"Struts2_0100_Hell0"项目中,你可以学习如何配置资源文件(properties)以实现不同语言的切换。 6. **表单验证**:Struts2内置了强大的表单验证机制,可以对用户输入进行前端和后端的校验。通过定义 validation....

    Struts2简单数据校验源码 20120417

    本资料"Struts2_1100_SimpleDataValiation"提供了关于Struts2简单数据校验的源码,这将有助于我们深入理解Struts2的数据校验机制。 1. **Struts2数据校验框架概述** - Struts2的数据校验框架是基于OGNL(Object-...

    Struts2数据校验与国际化

    在“Struts2数据校验与国际化”这一主题中,我们将深入探讨Struts2如何通过不同的验证机制确保数据的有效性,以及如何通过国际化功能提供多种语言的用户体验。 首先,数据校验是任何Web应用程序中的关键环节,它...

    struts2笔记之校验表单信息

    总结来说,Struts2的表单校验机制提供了多种灵活的方式,开发者可以根据实际需求选择适合的校验策略,确保用户输入的数据准确无误,从而提高应用的安全性和稳定性。无论是使用XML配置文件、注解还是自定义校验方法,...

    Struts2中的validation_多国语言版 国际化i18n+struts2数据校验.zip

    通过研究这些代码,你可以更深入地了解Struts2的数据校验和国际化是如何工作的,以及如何在自己的项目中实现它们。 总的来说,这个压缩包提供了一个全面的学习资源,涵盖了Struts2框架中的关键功能:数据校验、前端...

    struts 2 基础2__继承ActionSupport完成输入校验

    在基础的Struts2应用中,我们常常会继承`ActionSupport`类来实现输入校验,从而提高代码的复用性和可维护性。 `ActionSupport`是Struts2提供的一种基础Action实现,它包含了默认的行为,如错误处理、国际化支持和...

    Validate_code.rar_struts valida_struts valida_struts validate_v

    在Struts框架中,`validate`是用于表单验证的重要组成部分,帮助开发者实现业务逻辑中的数据校验。 在`struts validate`中,验证过程通常分为两个阶段:客户端验证和服务器端验证。客户端验证通常使用JavaScript...

    Java实训教程 Java软件开发实战 Java开发框架struts2介绍 共12个章节.rar

    【课程大纲】 struts2_1_入门介绍 共29页.pptx struts2_2_Action详解 共43页.pptx struts2_3_配置参数详解 共47页.pptx struts2_4_OGNL 共71页.pptx ...struts2_表单校验失败跳input视图问题 共13页.pptx

    Struts2_Validation

    综上所述,"Struts2_Validation"文件包很可能是围绕如何在Struts2中进行有效数据验证这一主题展开的,包括如何配置Validation.xml,编写验证规则,处理验证错误,以及如何结合其他Struts2特性进行更复杂的验证操作。...

    Java实训教程 Java软件开发实战 Java开发框架介绍 struts2 SpringMVC等共20多份课件资料.rar

    struts2_表单校验失败跳input视图问题 共13页.pptx SpringMVC_1_开发环境搭建 共41页.pptx SpringMVC_2_HelloWorld 共19页.pptx SpringMVC_3_方法入参 共41页.pptx SpringMVC_4_方法返回值 共25页.pptx SpringMVC_5...

    Java实训教程 Java软件开发实战 Java开发框架介绍 struts2_表单校验失败跳input视图问题共13页.pptx

    ### Java Struts2框架中的表单校验及处理机制 #### Struts2简介 Struts2是一个基于MVC(Model-View-Controller)设计模式的Java Web应用框架,它简化了Web应用程序的开发过程,提供了丰富的特性来支持复杂的业务...

    Struts2的输入校验

    通过这种方式,开发者可以轻松地在Struts2中实现输入校验,既保证了数据的正确性,又提高了应用的安全性。不仅如此,Struts2的灵活性还允许开发者扩展和定制自己的校验器,以满足不同项目的需求。总的来说,Struts2...

Global site tag (gtag.js) - Google Analytics