论坛首页 Java企业应用论坛

Struts2 验证框架新思维

浏览 6713 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-01-14   最后修改:2010-01-14
Struts2里可以使用xml或annotation定义验证规则,在进入action前会使用interceptor拦截并验证。有一部份验证器如String Length等还支持客户端自动生成JavaScript验证。但是在使用过程中,需要维护相当多的xml(简单的可以在action中使用annotation,但mode driven的不支持)。

我的原则希望:焦点集中在业务逻辑层,因为Service才是我们关心的业务

1)验证规则在Service层定义

如:

validation.addValidator("name",Validation.required(),Validation.length(5)).addValidator("password",Validation.required(),Validation.length(6))....


Validation.required()等,这些是返回自定义的验证类,有相应的validate方法。提供默认的错误提示消息,如:“必须填值!”,如果要支持i18n,可以Validation.required(i18nkey)

大多数情况下,name这些输入都是和database中的字段相关,数据库定义时都有如varchar(32)这样的,已经定义好了长度,如是数字的也有如number(5,2)这种定义好了精度,可以用一个生成工具,生成默认的和数据库相关的验证类,如user表,有name,password字段,可以生成

public class Vlidatiors{

public static class User{

public static Validator nameRequired(){...}
public static Validator nameLength(){...}

public static Validator passwordRequired(){...}
public static Validator passwordLength(){...}

... other rule
}
... other table
}

则Service中可以

validation.addValidator("name",Vlidatiors.User.nameRequired(),Vlidatiors.User.nameLength()).addValidator("password",Vlidatiors.User.nameRequired(),Vlidatiors.User.nameLength())....


2)服务器端验证在Service业务方法里执行
  如:


@Transactional
public void create() {

  if(getCreateValidation().validate()){//验证失败
    throw new BusinessError(getCreateValidation());
  }

   //验证通过,执行具体的业务逻辑
   ....

}

validation.validate()方法会循环执行验证规则,有不通过的,记录错误提示,在页面显示错误提示,见3)


3)JSP不需要写JavaScript,自定义标签,把验证规则翻译成JavaScript,支持onblur,表单onsubmit时校验。同时显示2)中的错误提示

如:<aaa:validation onsubmit="true" onlur="true" ...>


至于验证类,可以有很多,如Struts2里已经有有required,email等,“不要重复造车”,当然我不会傻到自己去重写,可以借用。还可以自己增加一些特殊的验证器(在开发中常用到,如比较验证器用来比较两个input text值==,<,>...,有一些输入有or的关系,如可以输入数字也可以输入字母等,有一些有数组输入,如可编辑表格的text的name会的 user[0].name 等)。

但关键的地方是:验证器里如何获取输入的值.ActionContext!使用ActionContext的ognl语法,可以从当前的value stack中findValue("user.name")...等
   发表时间:2010-01-15  
需要维护相当多的xml(简单的可以在action中使用annotation,但mode driven的不支持)。 为什么ModelDrive的不行呢,用一个FieldVisitor注解也可以呀。
0 请登录后投票
   发表时间:2010-01-16  
asialee 写道
需要维护相当多的xml(简单的可以在action中使用annotation,但mode driven的不支持)。 为什么ModelDrive的不行呢,用一个FieldVisitor注解也可以呀。


FieldVistor不可以生成JavaScriptr的,<s:form validate="true">...
0 请登录后投票
   发表时间:2010-01-16  
而且有相当多情况下,一个表单,但可以有几个action,如save,或delete,或update的button,通过js脚本进行提交。
这时,如果在xml中定义验证规则,jsp的form就不可以根据业务所需验证,因为如name,在update时需要验证,但在delete时,不需要。

另外一种就是动态的变量,如可编辑表格,input的数量,名字都是根据数据库的数量变化的,不可以静态地在xml或annotation中定义好,sturts2是没有对应的验证类的。

0 请登录后投票
   发表时间:2010-01-18  
yuanhuiwu 写道
而且有相当多情况下,一个表单,但可以有几个action,如save,或delete,或update的button,通过js脚本进行提交。
这时,如果在xml中定义验证规则,jsp的form就不可以根据业务所需验证,因为如name,在update时需要验证,但在delete时,不需要。

另外一种就是动态的变量,如可编辑表格,input的数量,名字都是根据数据库的数量变化的,不可以静态地在xml或annotation中定义好,sturts2是没有对应的验证类的。




好像可以对应每个action定义一个验证文件吧
0 请登录后投票
   发表时间:2010-01-18  
是的,actoin.java是可以。但jsp有一个form的但对应多个action的情况下,<s:form validate="true"时,js就会与业务相冲。通常action中会对应几个vo(po)接收数据,更复杂的情况是vo里还有bean。如User类里还有一个Address类,vistor验证器也无法满足要求。写业务逻辑时,还要去维护数量众多的xml将时件烦琐的事。即然xml可以做到与业务代码解耦。
0 请登录后投票
   发表时间:2010-01-18  
1. 可以基于数据库约束来生成验证类为什么不能基于它来生成验证的XML然后使用现成的难框架实现验证?只要你对自动生成的东西有信心,那么生成的东西对你来说就维护的代价是很低的,只要一个命令行而已。
2. Action可以做为domain model package的facade,验证逻辑可以在Action里面,Service可以完全关注领域问题,对验证无意识。当然这只是个设计问题,不管怎么样,以你的方案人都得手工编写验证逻辑,或者自定义你的拦截器,往往共同抽取不满足需要时都得为特殊部分做特殊处理,可能少不了又一配置,这不是轮子了吗?
3. 过于局限在自动生成里,自动生成的js验证是好,但这可能是美好的愿景,为了满足挑剔的客户很多时候都得自己写js来完成页面上花俏的表现,这些简单的验证判断自己写写真是没啥~~缺点就是需求改起来太囧,不如你自动生成的容易维护。
0 请登录后投票
   发表时间:2010-01-18  
jashawn 一针见血,但不得不承认,就是这些简单的验证,90%都是重复来重复去的工作,如是否是int?长度多少?是否是日期?最大?最小?...复杂逻辑的验证器可以抽出来的,就抽出来。比较个性的验证(如与主键记录重复)当然需要写代码(目前无论使用什么验证框架都无法逃避)。
我们正在做一些测试,
1)增加一个拦截器拦截throw new BusinessError(getCreateValidation()); 得到的error转成action field error
2)增加一个自定义标签,生成javascript
3)验证器类增加ComparisonValidator(==,<,>...),OrValidator(输入可以是"日期",也可以是"数字"这种情形...),FileValidator(Struts2 的文件上传验证不定义在action配置xml中)DecimalRangeValidator(验证number(5,2)或decimal(5,2)...),TimeRangeValidator,TimestampRangeValidator,另外借用Struts2已有的一些validator

验证规则在Service根据业务定义,显然验证与业务靠近,但Service层代码增多
jsp减少90%以上的javascript代码输入,开发人员不再需要写难以调试的js。

测试通过的话,如有需要,可以帖代码上来
0 请登录后投票
   发表时间:2010-01-18  
好吧,我期待你的framework。

验证其实有两个方面,对输入的验证和对输入进行业务验证,你所做的所说的都在解决输入的验证,Ok,我所说的Serivce不应该去考虑对输入的验证,但必须得关注对输入进行业务验证。
比如你提交一个房型,验证框架应该解决对房型字段约束的验证,而在这个用例里,你必须验证这个房型提交到的酒店是否存在,这应该由Service来完成。

所以你们的idea应该侧重于扩展对输入的验证,并建立一系列的设施,比如jsp tag,自动生成。其实你们的核心思想就是基于数据库约束来生成。
我看到之后第一个念头就是你们可能倾向于自底向上的开发。
另外js写验证没有那么复杂,相对于用js来控制页面元素而言验证逻辑很简单,调试它们并不困难,而且有很多js库可以用比如jquery,YUI之类的。
0 请登录后投票
   发表时间:2010-01-18  
Yes,输入验证!

业务验证,跟具体业务相关,在Sevice中,会如

if(重复记录){
  throw new BusinessError(i18nkey);
}

BusinessError是一个unchecked exception,@Transactional才会达到如期效果
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics