- 浏览: 338901 次
- 性别:
- 来自: 新加坡
-
文章分类
最新评论
-
xiuluocd:
ok,受益匪浅
[转贴]System.getProperty()参数大全 -
xiaohuafyle:
这个不能算是bug吧,weblogic用的jdk版本一直都很老 ...
项目积累:Weblogic -
macemers:
请问楼主 has_readed作为计数器,是如何防止网络阻塞的 ...
Socket、Thread的使用记录 -
xutao5641745:
higkoo 写道请教一个问题,我在编译Jmeter的时候,发 ...
[转贴]System.getProperty()参数大全 -
zhaoyu_h:
加油。。。啊。。。加油。。。 谢谢啦。。
[转贴]System.getProperty()参数大全
不得不承认我用了太久的Struts1,但实际上并没有太多好的回忆,在大家都忙着学习Seam、JSF、SpringMVC和Struts2的时候我还不得不使用老掉牙的Struts1。好在每次用还是会用新收获,前提是你跳槽到新公司 -__-!!
背景:说正题,新公司新项目,主体不在Web App上面,因为系统主要用于数据管理对数据库的完整性和准确性,所以需求上光是验证就有60页的文档,对每一条进入系统的数据都有很严格的要求:包括单个数据和数据之间的关系都有详细的规定,由于我负责的是单个数据的验证,所以本文只关心单个数据的有效性验证。
方案:既然用了Struts,那就很难离开ActionForm(当然也有狠人直接把ActionFrom也干掉@_@),用了ActionForm自然而然的选择Struts Validation。Struts Validation不知道算不算目前Web表现层最好的验证方案,但是肯定是使用最广泛的一种,但是它仍然不够用。
又跑题了,所以对于单个用户录入数据的有效性验证仍然采用Struts Validation,在做过一些改动后,Struts Validation还是能很好的完成这项工作。
1.使用validwhen来做简单的交互性验证
这个网上经常可以搜到,也算是Validation里面最复杂、功能最花哨的一部分,单单为了实现这个功能,Validation就用了4个以上的类去工作,包括字符串的解析这种比较繁琐的工作。它的主要用途是用来做一些简单的交互性的验证,比如A不为空的时候B必须有值,可以做点简单的交互验证哦,但是我并不是很喜欢这东西,写表达式测试起来挺烦的,但是2,3个数据的相互制约还是可以考虑,最常用的就是上面说到的要求,我们可以这样写:
<field property="name" depends="validwhen"> <arg position="0" key="label.name" resource="true" bundle="common" /> <var> <var-name>test</var-name> <var-value>((age == null) or (*this* != null))</var-value> </var> </field>
age不为空的时候name也不能为空,很常见的验证要求。由于这东西每次调试都要重启Server,很烦人,所以我也没做过多的尝试,那个表达式写起来也挺折腾人的,一不小心就失败。如果有兴趣可以参考Validation官方文档中的几条要求做更复杂的表达式来给你的表单做验证。当然这东西还是问题多多的,也可以说凡是用配置文件搞出来的东西,就不会百分之百的符合你的要求。
2.使用indexedListProperty为一个循环fields
这也是Validation里面默认就提供的功能,如果你的表单中包含循环元素生成的元素的时候就可以考虑用indexedListProperty来进行验证,这个很简单,只给出例子:
<field property="name" indexedListProperty="friends" depends="required"> <arg position="0" key="label.name" resource="true" bundle="common" /> </field>
indexedListProperty经常与validwhen一起用。
3.自定义validator
Validation里面提供的都是写基本的验证,更多时候需要自定义一些验证来整合我们的业务,所以validation提供了它的扩展接口,其实也就是用配置文件validator-rules.xml的方式来扩展validator。有了这个东西,你可以把任意复杂度的东西放在里面做你想做的验证。这个扩展功能很得人心,这样Validation的灵活度就非常大,更好的做到重用。
<validator name="name" classname="com.cyan.action.validator.CommonValidator" method="validateName" methodParams="java.lang.Object, org.apache.commons.validator.ValidatorAction, org.apache.commons.validator.Field, org.apache.struts.action.ActionMessages, org.apache.commons.validator.Validator, javax.servlet.http.HttpServletRequest" msg="msg.error.name"> </validator>
指定了这个新的validator,你可以任意加入自己的验证机制,在com.cyan.action.validator.CommonValidator中增加validateName()方法,注意在配置文件中已经默认指定了适合Struts ActionForm所需要的参数,你也需要在方法里使用,这样才能整合进Struts Validation并且方便的使用它的Message popup机制。这样你就可以实现你自己的validator:
public static boolean validateName(Object bean, ValidatorAction va, Field field, ActionMessages errors, Validator validator, HttpServletRequest request) { String value = null; Integer result = null; value = evaluateBean(bean, field); // add your validation logic here if (!GenericValidator.isBlankOrNull(value)) { errors.add(field.getKey(), Resources.getActionMessage(validator, request, va, field)); return false; } return true; }
这样的扩展写着非常的自如,因为本身Validation对这个CommonValidator的要求很低,它不需要继承和实现任何接口类,当然你也可以继承org.apache.struts.validator.FieldChecks去继承它的一些基本验证。你也同样可以修改validator-rules.xml里面的默认validator指定到你自己的验证规则上。
4.JavaScript客户端验证
这个功能很早就在Struts中得到了支持,因为是客户端就验证了,可以有效减少服务器端的负载,而且Struts Validation JavaScript模式还可以提供Client Server两端验证这种双保险机制,可以减少不少工作量和维护工作。要使用它除了在服务器端进行基础的validation配置以外,还需要给你的页面form增加一点东西(参考:http://www.xker.com/page/e2007/0727/28232.html):
< script language="Javascript1.1" src="js/validator.js">< /script>
< html:javascript formName=”loginForm”>
< html:form action="manageContract.do" onsubmit="return validateLoginForm(this);>
大概是这么写,显然这不是我想说的,网上找这个很容易。我要说的是JavaScript验证方式的问题: JavaScript方式的验证会自动将后台验证代码转化成JavaScript,毕竟是框架生成的,会导致每页JS代码暴增,会影响页面加载速度;还有一个问题就是你自己定义的验证人家没法给你转化成JS,怎么办?用它的JavaScript Plugin。
//TODO
5.验证器的继承
上面已经提到过,系统对验证的要求比较高,common validation就多达100多个,那么按照validation默认的方式对每个ActionForm去写这重复的东西很不现实,所以Validation提供了一个继承方式:
<form name="BaseForm"> <field property="name" depends="required"> <arg position="0" key="label.name" resource="true" bundle="common" /> </field> </form>
<form name="loginForm" extends="BaseForm"> </form>
这样loginForm就会默认的包含一个name的validator,增加一点配置的重用性。在系统启动的时候,validation会检查所有form的parent并进行合并validator,它会让“子类”form里面的validator覆盖父类的,也就是说你继承了BaseForm,如果有不同的验证,你可以把它覆盖掉。
6.扩展Validation
这里说的扩展Validation不是说写那个validator-rules.xml,我要说的是Validation验证还是太简单,我想更好的使用它就得在它的基础上进行扩展。用框架的时候为了使得框架更适合我们的项目,自然而然的选择去扩展,在Struts1中我们最经常看到的就是扩展org.apache.struts.action.RequestProcessor中的方法,比如其提供的
protected boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) { return (true); }
这是Struts框架中提供的一个很常用的扩展点,不过自打有了AOP之后它有点落寞,不妨碍我继续数用 :P。
之所以要扩展,问题就来自于上面的使用validation继承,这个继承的问题在于你的子类form会被强迫加入所有父类的validator,比如父类里面有一个age的验证,而你子类里面也被强制增加了这个age验证器,不管你有没有age这个字段。我不知道是validation没想明白还是我没用明白,这样的继承机制谁还敢用,所以我使用下面的扩展方案,如果有其他办法,希望不吝赐教。
在这里先抱怨一下,Validation的确是个好东西,但是它的代码显然是积怨太深,每次验证出问题我去调试跟代码都会很痛苦,因为它写的的确很难懂,好多类、好多方法掺和在一起,也许是我无法理解那些大师们的用意。
扩展org.apache.struts.validator.ValidatorForm中的validate()方法,当然你的类是可以继承任意ValidatorForm的子类,我们继承的是LazyValidatorForm。
这个扩展类里面的代码就比较多了(主要因为里面bug比较多),这里只给出部分代码段,主要实现的功能有:
1.子类实现“伪”继承,就是说子类只根据需要取父类的validator
2.validator支持多个名字,如:<field property="name, person.name" depends="required, length">
由于项目中使用的是LazyValidatorForm,form表单里的名字是以map方式传回Action,并支持POJO的populate,所以我们的验证器会有对person.name这种字段的验证,当然扩展的时候也主要在这里出现问题。
首先是修改validator加载的来源:
public class BaseForm extends LazyValidatorForm { public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ServletContext application = getServlet().getServletContext(); ActionErrors errors = new ActionErrors(); String validationKey = getValidationKey(mapping, request); // Override code Validator validator = // Resources.initValidator(validationKey, this, application, request, errors, page); Validator validator = initValidator(validationKey, this, application, request, errors, page); try { validatorResults = validator.validate(); } catch (ValidatorException e) { logger.error(e.getMessage(), e); } return errors; } }
顺便你还得提供一个类似于org.apache.struts.validator.Resources.initValidator()的方法:
public Validator initValidator(String key, Object bean, ServletContext application, HttpServletRequest request, ActionMessages errors, int page) { ValidatorResources resources = Resources.getValidatorResources(application, request); Locale locale = RequestUtils.getUserLocale(request, null); Form form = resources.getForm(locale, key); // Override codes here start if (form != null) { List lFields = (List) getPrivateField(form, "lFields"); Map hFields = (Map) getPrivateField(form, "hFields"); filterFields(lFields, resources, hFields); } // end Validator validator = new Validator(resources, key); validator.setUseContextClassLoader(true); validator.setPage(page); validator.setParameter(SERVLET_CONTEXT_PARAM, application); validator.setParameter(HTTP_SERVLET_REQUEST_PARAM, request); validator.setParameter(Validator.LOCALE_PARAM, locale); validator.setParameter(ACTION_MESSAGES_PARAM, errors); validator.setParameter(Validator.BEAN_PARAM, bean); return validator; }
(代码中的private property accessor参考:http://snippets.dzone.com/posts/show/2242)
因为这并不是框架中提供的一个扩展点,所以这个代码看起来挺别扭,明明只要修改它一句话,但其他的你也得加上。
这样你就可以修改它加载validator的方式,不过这只是个开始,validation并不希望你去这么做,真正的麻烦还在后面。其实麻烦已经出现了,在上面这段覆盖initValidator()的方法中我已经被迫使用了Java reflection中的private property accessor,再一次提醒你人家validation不想你去碰它,god bless me。
这样总算是获得了Struts Validation里面针对没一个form的validator集合,实际是存放在ValidatorResources中的org.apache.commons.validator.Form中的一个List类型的多个org.apache.commons.validator.Field。然后我们就可以任意的去修改它们,发挥你的聪明才智去适应你的需求吧!记得在修改完毕以后需要完璧归赵:ValidatorResources资源被存放在ServletContext里面作为全局变量保存,你在修改完Form里面的lFields以后需要重新放回去,这个很关键,否则你修改的东西就只能生效一次,下次再来的时候人家就不认识你咯。
至于如何修改我就不给出代码了,有兴趣的朋友可以看看附件,代码我简单改过,主要是去掉了公司的信息,代码还在测试使用中(因为要适应我们项目的需要),也许你会感到代码写的比较ugly,狂多的for循环和if else,写的时候着实耗费我不少功夫去调试。
这样就算是把我目前知道的有关Struts Validation的一些复杂应用总结完了,其实验证就是一个纯体力活,写这些东西就是为了减少奋战在一线的战友们减轻点负担,hope it will help you。
- BaseForm.rar (3 KB)
- 下载次数: 35
发表评论
-
多种问题 一种解决方案:使用ANT管理部署应用服务器
2008-07-12 01:46 4070ANT在Java界和开源世界里面的地位大家都知道,虽然 ... -
Socket、Thread的使用记录
2008-04-03 16:35 2758做了太多时候的Web项目 ... -
项目积累:Weblogic
2007-08-22 17:54 2213新项目中最大的收获就是Weblogic的使用和管理,由于客户的 ... -
项目反思:DetachedCriteria需要吗?不需要吗?
2007-07-09 23:16 3002Hibernate3中提供了DetachedCri ... -
JUnit方案 DetachedCriteria模拟求解
2007-07-04 16:36 1868新项目客户对测试的要求比较严格,要求单元测试的覆盖率为 ... -
Spring 移植到WebLogic10上出现的Log4j.properties错误
2007-06-10 23:31 6331问题是在Tomcat移植到Weblogic10上出现的问题,主 ... -
[转贴]Clustering经典范文学习
2007-05-12 10:37 1949Cluster对于没有去实现的人还是相当神秘的东西,先从基础 ... -
JavaEye活动记实 Gavin King见面会以及Robbin Hibernate性能调优
2007-04-24 00:05 42954月19日,如期赶到交大 ... -
使用Velocity Swing制作的代码生成工具
2007-04-18 13:39 2885一个使用JEE开发的项目中将会存在大量的重复代码,这是每个开发 ... -
J2EE性能提高(Struts+Spring+Hibernate)
2007-04-17 22:33 3500新近的项目是一个BOSS级的计费系统,性能和稳定性的要求比较高 ... -
[转贴]System.getProperty()参数大全
2007-04-17 17:42 45614一直做Web应用一般不会用到这些东西,今天在搞一个代码生成器的 ... -
Spring2学习笔记
2007-04-15 22:33 1978学习和使用Rails正开心 ... -
[原创]Struts Validation框架中验证循环产生的Text框
2006-01-11 14:18 1935前几天做到一个validation验证使用<iterat ... -
[原创]JSP页面通过Form控制Beans属性
2006-01-14 16:29 1535这个问题我曾经在社区提问过,不知是当时没问清楚还是怎样,回答是 ... -
项目总结(Ajax+Struts+Spring+Hiberante+SQLServer2000) 第一部分
2006-08-06 16:09 1865总算将一个项目勉 ... -
我的乱码问题处理汇总
2006-08-06 22:32 3842乱码对于使用非英语文 ... -
项目总结(Ajax+Struts+Spring+Hiberante+SQLServer2000) 第三部分
2006-08-06 22:56 1592因为本次项目是政府项目,所以数据库服务器采用SQLServer ... -
[讨论]有关Spring+Hibernate更新数据库的操作
2006-09-20 00:05 2884最近老和同事争执一个S ... -
Hibernate事务管理读书笔记(不断添加中)
2006-09-20 12:28 6302昨天发了一个有关Hiberna ... -
[转贴]JDK5下避免DAO代码重复--原文名称:不要重复 DAO
2006-10-08 15:19 1786由于 Java™ 5 泛型的采 ...
相关推荐
Struts-validation的2种方法 - **基于 ActionForm**:通过在 `ActionForm` 类中重写 `validate()` 方法来验证数据。 - **基于拦截器**:使用 Struts2 的拦截器进行数据验证。 #### 30. JavaScript起到什么样的...
pimpinella_3cd_01_0716
FIB English learning
X86-jq安装包
AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
大圣挪车小程序1.3.5 前端
Manus.im 产品及开发团队研究报告.pdf
AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
sun_3ck_01a_0918
下载 1. 单击“立即下载”,以下载该文件。 2. 出现“文件下载”窗口后,单击“保存”,以将文件保存到硬盘。 安装 1. 浏览至文件下载目标位置并双击新下载的文件。 2. 仔细阅读对话窗口中显示的发布信息。 3. 下载并安装对话窗口中标识的任何必备项,然后再继续。 4. 单击“Install”(安装)按钮。 5. 按照其余提示执行更新。 安装 1. 将解压的文件复制到可访问Windows的介质。 2. 将系统重新引导至Windows操作系统。 3. 打开“服务器管理器”->“设备管理器”->“存储控制器”,然后单击“PERC控制器”。 5. 单击“更新驱动程序软件”,并按照提示更新驱动程序。 4. 重新引导系统以使更改生效。
支持所有操作系统一键安装。
matlab程序代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
swanson_01_1106
AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
sun_3ck_01_0919
各城市方言距离数据-中山大学岭南学院产业与区域经济研究中心 方言距离是指两种或多种方言之间的相似程度或差异程度。参考中山大学岭南学院产业与区域经济研究中心的刘毓芸等(2015)文献。他们基于方言树图,并参考《汉语方言大词典》和《中国语言地图集》对方言的划分,将汉语方言从宽泛到具体分为以下几个层级:汉语→方言大区→方言区→方言片。为了量化县与县之间的方言差异,他们采用了一种赋值方法: 若它们分属不同方言大区,则距离为3。: 若两个县同属一个方言片,则它们之间的方言距离为0; 若两个县属于同一方言区但不同方言片,则距离为1; 若它们属于同一方言大区但不同方言区,则距离为2; 方言距离是一个反映方言之间相似程度或差异程度的重要指标,它在语音识别、方言研究等领域具有广泛的应用价值。 参考文献:[1]刘毓芸, 徐现祥, 肖泽凯. 2015. 劳动力跨方言流动的倒U型模式[J]. 经济研究, 50(10): 134-146+162. 指标 语系、语族、方言大区、方言区/语支、方言片/语种、Supergroup、Dialect、group、Sub-dialect、groupPref_1、Pref_2、DiaDist、PrefCode_1、PrefCode_2等等。