月光疾风

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

上一篇总结了JSP前台验证的常见方法,这一篇说一说后台验证的方法。我把后台验证大体分为两类,一类是非Ajax方式,一类是Ajax方式。

1. 非Ajax方式

1) 使用方法:正常提交表单,在Action层的某处判断表单中的内容是否正确。假如后台使用了Struts2框架的话,这个“判断”应该是在***Action类的某个方法中,可以是execute类的方法,也可以是validate类的方法。可能放在validate类的方法里,逻辑会更清晰,毕竟大量的if-else或者try-catch代码段比较纠结。

    需要特别注意的是,验证失败,Struts2默认返回<result name="input"></result>所指定的物理视图。如果直接是一个jsp页面,基本上没有什么问题。如果是另一个action,为了保持信息不丢失,一般type应该是chain。简单的描述一下目前的处境:

1 <action name="action1" class="FooAction" method="foo">
2 <result name="success">***</result>
3 <result name="input" type="chain">action2</result>
4  </action>
5  <action name="action2" class="BarAction" method="bar">
6 <result>***</result>
7  </action>

在跳转到action1的时候,如果在执行FooAction.foo()方法之前的验证没有通过,程序会跳到input指定的物理视图action2中。但是因为input这个result的类型是chain,所以一切信息都会保留,包括验证不通过的信息。这样一来,在进入BarAction.bar()方法之前,又被BarAction的拦截器拦截,发现验证不通过,需要一个名为input的result。因此action2也要添加一个input。这还不算是什么,真正困难的是,既然没有机会进入BarAction.bar(),那么<result name="input">物理视图</result>中的物理视图如果需要通过bar()方法获得一些数据,该怎么办呢?解决方法也是有的,可以再添加一个action的配置:

<action name="action3" class="BarAction" method="input">
<result>***</result>
</action>

这个新增加的action,最重要的是method名字必须是input。此时,action1的input所chain的action不再是action2,而是action3。那么BarAction.input()方法仅仅需要简单地调用一下bar()就可以了。至于为什么这样就能解决问题,我会另外写一篇文章简单说一下。如果多个方法都需要一个input和它对应,或许可以给action3添加一个参数,或者为每个动作写一个Action类(而不是每个对象对应一个Action类)。我没有试过给action3增加参数这个方法,只是感觉它可以解决问题。

2) 错误信息显示:如果验证失败了,可以通过 ActionSupport.addFieldError()方法向前台传递信息。addFieldError()第一个参数指定了要把错误信息显示在哪个表单元素的上方,第二个参数指定错误信息。当然,如果验证后跳转到的页面里有<s:fielderror><s:param>某表单的name属性的值</s:param></s:filederror>,信息就会在这里显示,而不是显示在那个表单上方去。

3) 优缺点:刷新整个页面,一方面给用户带来不好的体验,另一方面需要消耗更多的时间,占用更多带宽。而且还有上面描述的那个chain的问题。几乎没有什么优点吧。

2. Ajax方式

1) 使用方法:很多js框架都提供了很方便的ajax提交功能以及结果处理方法。比如prototype.js或者jQuery.js。Struts2默认使用的是prototype.js。使用Ajax,需要引入json2.js,prototype.js,以及jsonplugin-0.32.jar这三个文件。

在提交按钮的事件处理函数里,正式提交之前,使用以下代码:

1 function validateAddInAction(){
2 var url = 用于验证的action; //此action指向一个用作验证的方法

3 var params = Form.serialize('要提交的form的id');
4 var ajaxreq = new Ajax.Request(
5 url,
6 {
7 method:'post',
8 parameters:params,
9 onComplete:processResponse, //ajax返回结果后的处理函数
10 asynchronous:true
11 }
12 );
13 }

下面是processResponse()的例子:

1 function processResponse(request){
2 var res = JSON.parse(request.responseText);
3 var temp = res['Action类中某个属性名'];
4 ......
5
6 var form = document.forms[0];
7 form.action = "正式提交用的action";
8 ......
9 form.submit();
10 }

上面的代码里,temp=res['']中的参数,是Action类中某一个属性的名字。比如Action中有private String a; private String b;以及它们对应的getter(),setter()方法,那么就可以在ajax返回的结果中通过res['a']和res['b']获得它们的值。

 

除此之外,action的配置也要做一些修改:

1 <action name="用于验证的那个action" class="FooAction" method="f">
2 <result type="json"></result>
3 </action>
4
5 并且,这个<action />的外层的<package />的extends的值由struts-default改为json-default。

上述配置中,f()是用于验证的方法。返回结果的类型是json,所以不需要指定物理视图。注意,假如正式提交的action对应的方法是foo(),对应的验证用的方法命名为validatefoo(),要在foo()之前添加@SkipValidation,这是为了防止进入foo()之前,再一次自动进入validatefoo()方法验证一次。

2) 错误信息显示

验证不通过,错误信息可以通过Action的某个属性传递到前台,具体方法见上面的说明。

3) 优缺点:似乎只有优点。

posted on 2010-11-22 21:30  月光疾风  阅读(3071)  评论(0编辑  收藏  举报