Chinaunix首页 | 论坛 | 博客
  • 博客访问: 26321099
  • 博文数量: 2065
  • 博客积分: 10377
  • 博客等级: 上将
  • 技术积分: 21525
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:50
文章分类

全部博文(2065)

文章存档

2012年(2)

2011年(19)

2010年(1160)

2009年(969)

2008年(153)

分类: Java

2010-06-14 22:30:35

表单数据校验

时间:2010-6-14

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

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

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

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

相关问题:如何高效地使用反射机制?

 

使用框架的校验框架

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

 

个人感觉:这个东西将来会用得比较多的。因为校验是避不可少!在Django里面其实就是一个中间件。

 

示例:

1、编写Action校验器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;

    }

}

其实这个Action没有做什么的。只是简单用来承载客户端传过来的数据而已了。

第二步:定义配置文件

<package name="IOCDemo" extends="struts-default">

        <action name="ValidationAction" class="tutorial.ValidationAction">

            <result>/Output.jspresult>

            <result name="input">/Input.jspresult>

        action>

package>

表示:正常就转到Output.jsp页面如果不正常就转到Input.jsp页面。

第三步:定义这两个视图JSP页面

Input.jsp页面

<s:form action="ValidationAction">

    <s:textfield name="reqiuredString" label="required string" >s:textfield>

    <s:submit />

s:form>

其中表单名称为 reqiuredString 就是我们的里面的值!Action里面的值了。

 

Output.jsp页面

Required String :

其中的值是我们所提交的数据值的!

 

编写:验证器

要注意:一个验证器是与一个Action相匹配的。这里面的Action类名称为ValidationAction

位于哪个包呢?tutorial 。所以我们可以在这个包下面定义我们的验证器了

ValidationAction-validation.xml文件

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

DOCTYPE validators PUBLIC

          "-//OpenSymphony Group//XWork Validator 1.0//EN"

          "1.0.2.dtd" >

<validators>

    <field name="reqiuredString">

        <field-validator type="requiredstring">

            <message>This string is requiredmessage>

        field-validator>

    field>

validators>

相当于我们以提交过来的表单值进行一次过滤处理了。

这个功能其实就是相当于我们在servlet层进行一次数据过滤处理。如果为空的话就直接回传数据到客户端。

 

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

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

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

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

我感觉它的表单框架也是个不错的JS框架!

在上面的例子中,我们通过创建ValidationAction-validation.xml来配置表单校验。Struts 2.0的校验框架自动会读取该文件。

 

 

那这么多的配置文件它是如何来查找的呢?现在来看看吧!

 

假设以下条件成立:

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

如果Dog要被校验,框架方法会查找下面的配置文件(其中别名是Actionstruts.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

 

目前已有的校验器

< 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进行分离,那样的话我们就不需要把一些验证功能放到Action里面了。而且还可以快速验证表单数据。所以这一招非常好用。记下了。

 

 

验证框架是一款非常不错的东西将来在我的项目中要经常多的使用哦!

 

在使用校验框架时,请不要忘记通过在资源文件加入invalid.fieldvalue.xxx字符串,显示适合的类型转换出错信息;或者使用conversion校验器。

阅读(859) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~