struts2的校验跳转

   ORDER项目,struts2表单使用validation框架进行校验,有错误信息时需要在当前表单提交页面把错误信息打出来,本来是很简单的一个需求,在这次使用struts2中却出现了出乎意料的错误。

现象如下:

   通过test1Action查询数据后进入a页面,a页面的表单提交到test2Action,出错后回到a页面显示错误信息,在这个Action的配置中input时,指到一个jsp,结果虽然进入了a页面,但是在test1Action中查询到的数据全部没有。

   结果发现需要配置result的跳转type为chain(此种方式的利弊下面会介绍),比如此处需要设置

<result name="input" type="chain">test1ActionMethod</result>(test1ActionMethod为请求test1Action中某个方法时配置的方法name),并且对test1Action的拦截器要做如下配置:           

   <interceptor-ref name="defaultStack">
          <param name="workflow.excludeMethods">test1ActionMethod(要访问的Action中的方法名)</param>
   </interceptor-ref>

同时test1ActionMethod要配置input类型的result,因为chain的跳转方式,会把上一个action的errors同时带入下一个要跳转的action,被跳入的action的拦截器发现有errors时,就会将result设置为input,但是因为配置了对于要访问的action中的方法,不进行校验拦截器拦截,所以在有errors的同时,请求还是会进入test1Action,能够再次获取进入a页面的数据,问题解决,下面附上对于几种跳转方式的说明,网上找的,嘿嘿。

 

 


 

 

数据验证的调用是包装在workflow拦截器里,

  我们看看workflow拦截器在struts_default.xml中的定义,它是放在默认的defaultStack拦截器组里,相关顺序如下:

 

  <interceptor-ref name="params"/>
  <interceptor-ref name="conversionError"/>
  <interceptor-ref name="validation"/>
  <interceptor-ref name="workflow"/>

  params与conversionError这两个拦截器在workflow的前面,它们的工作是从request中把数据转成正确的Java类型数据,以供后面处理。validation拦截器实质是AnnotationValidationInterceptor 与我们这里谈的数据验证不是一回事,它只判断有没有@SkipValidation注解,如果有就不会路过数据验证,只是起一个开关作用。

  当workflow拦截器触发时,它先检查当前请求的action是否实现了Validateable 接口,如果实现了该接口,则调用 validate()方法:如果这个方法处理时发现有数据验证不通过,则会生成一个错误信息并交给ValidationAware 的方法去存储这些出错信息。当validate()方法执行完毕,workflow拦截器还要调用ValidationAware 的hasErrors()方法,看看是否有出错信息生成,如果有出错信息,就中断当前action的执行流程,返回"input"字符串,一般我们是在配置文件struts.xml里配置"input"返回结果的跳转页面。

 

 


 

 

action的默认结果类型是dispatcher,而action之间发送请求是不能直接用该结果类型的。一般来说,可选的结果有 redirect、redirect-action、chain。前两种都是属于页面跳转,也就是说,发送请求以后,地址栏的地址会刷新为被请求的 action的地址,而chain则不会更新地址。

redirect-action : “这个Result使用ActionMapperFactory提供的ActionMapper来重定位浏览器的URL来调用指定的action和(可选 的)namespace. 这个Result比ServletRedirectResult要好.因为你不需要把URL编码成xwork.xml中配置的ActionMapper提 供的模式. 这就是说你可以在任意点上改变URL模式而不会影响你的应用程序. 因此强烈推荐使用这个Result而不是标准的redirect result来解决重定位到某个action的情况.”---webwork2的说法。

redirect : “调用{@link HttpServletResponse#sendRedirect(String) sendRedirect}方法来转到指定的位置。HTTP响应被告知使浏览器直接跳转到指定的位置(产生客户端的一个新请求). 这样做的结果会使刚刚执行的action(包括action实例,action中的错误消息等)丢失, 不再可用。”

简单说,两者的共同点是,地址栏会变化,所有前一个action的请求参数都会丢失,当然也包括action的属性值也会丢失。路径写法稍有不 同,redirect-action请求下一个action时,不带后缀.action,而redirect和普通URL写法一致。redirect- action支持param来附加请求参数,但是这往往会导致ServletActionRedirectResult报找不到xxx属性的警告,这大概 是由于无法识别是IOC注入,还是参数附加URL导致的,虽然是WARN级别,不过宁可写成xxx?a=x&b=y的形式,而&还需要写 作&amp;的格式,否则会报xml格式错误。(另外,这种url形式,作为param的actionName的值也是可以正常使用的)

chain :相当 于是forward,首先表现为地址栏不会改变,类似dispatcher,同时,它的特点是能够在多个action中共享表单传递过来的数据,同时,按 照action链的顺序,相关action的属性值也会传递下去,这表示在最后的视图页,你可以得到前面所有action的属性值(如果有get方法的 话)。对于多个action具有相同属性值的话,后续action会先使用前面的action的数据来进行赋值,然后再进行逻辑处理并传递下去。

看起来是很完美,可是却有很大的问题。如果后面的action需要调用前面action的属性值,他得保证具有同样的属性值,否则你无法接收到前面 action的值。他无法像redirect-action一样通过附加参数获取,他不支持xxx?a=x&b=y的形式。这将导致很大的耦合性 和无效参数的泛滥,无法通过配置文件传递参数也很麻烦。

另外,很困扰的一点就是,如果在action链靠前的action方法内出现错误(如action的hasError方法返回true)或者发生异 常,他就会强迫你定义input结果,包括后面的action也要定义,否则就会报错。而实际上,即使符合了以上条件,他仍不会执行后面的action, 而是直接跳到后面的action的input视图。除非发生错误的action返回input,并且type为“chain”,并且后一个action的 方法必须为input,否则后续方法不会执行,而直接定位到了最后的物理视图。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值