帮助我更好地理解Struts2,验证和有状态的操作

tpd*_*pdi 5 validation state struts2

据我了解,Struts2动作类实例(与Struts1不同)可以是有状态的,因为动作的每个GET或POST都会创建一个支持动作类的新实例.

我还看到有一个标准(?)习惯用法(模式?)来提供输入形式:相同的.jsp用作两个不同动作的View组件,如下所示:

<action name="showForm" class="defaultActionThatDoesNothingExceptReturnSuccess">
  <result name="success">inputForm.jsp</result>
</action>

<action name="validateAndProcessForm" class="realAction">
  <result name="input">inputForm.jsp</result>
  <result name="success">formProcessed.jsp</result>
</action>
Run Code Online (Sandbox Code Playgroud)

第一个操作只显示表单,而不验证输入或处理它..jsp中的表单发布到第二个操作:

<s:form action="validateAndProcessForm" method="post">
Run Code Online (Sandbox Code Playgroud)

并且第二个动作验证发布的字段/参数,如果表单的输入不完整或无效则返回"输入",或者execute如果输入完整且有效则返回实际调用操作类,从而处理表单并返回(例如)formProcessed.jsp显示的类似"谢谢你的意见!".

所以我们有这种"尖桩篱笆"的习语:

defaultAction-           -> realAction-
             |           |     |       |
             -> input.jsp-  <---       -> success.jsp
Run Code Online (Sandbox Code Playgroud)

这样做是为了第一次input.jsp显示,不调用验证(因此未显示验证错误),但是在点击该jsp上的提交按钮后,"真实"操作将验证输入,可能通过返回错误,调出input.jsp将显示的无效输入.

这使我们回到有状态的,非单身的行为; 因为该操作是有状态的,因此不能在GET或POST之间共享,并且每个实例仅针对该GET或POST实例化,所以该操作无法知道特定会话是否多次"GET"同一页面.因此让showForm.action永远不会验证和歌厅validateAndProcessForm始终验证(并显示错误,如果该参数是无效的),即使是GET是第一次一个特定的会话"GETted"该URL.

这就是为什么我们需要"围栏帖子":第一个动作只是为了显示表格,第二个动作是为了捕捉输入.

我的理解是否正确?是否有一种不那么冗长的方法来做到这一点,不是在初始GET上验证输入,而是在POST上验证,而不必为每个表单都有两个动作?

Dus*_*lmi 9

还有另一种方法可以在没有尖桩篱栅的情况下执行您想要的任务.默认情况下,验证拦截器不会为输入方法触发.因此,您可以将struts.xml更新为以下内容:

<action name="*MyForm" method="{1}" class="realAction">
  <result name="input">inputForm.jsp</result>
  <result name="success">formProcessed.jsp</result>
</action>
Run Code Online (Sandbox Code Playgroud)

使用此设置,您根本不需要空操作.当您第一次转到表单时,您将转到URL"inputMyForm",并将表单操作指向"MyForm".方法块中的{1}只意味着框架将调用与动作名称中的*匹配的任何方法.如果*match为空,则默认为execute方法.所以你得到以下几种行动:

  • inputMyForm将转到action类的input()方法
  • MyForm将转到action类的execute()方法
  • executeMyForm将转到action类的execute()方法
  • customMethodNameMyForm将转到操作类的customMethodName()方法

由于验证器拦截器排除了进入输入方法的任何操作,因此您可以为此操作设置所需的任何验证,并且只有在您提交表单时才会查找它.由于每次提交表单时都会执行execute方法,因此每次提交表单时都会进行验证.

此外,如果要扩展ActionSupport类,该类已经定义了input()方法,因此您甚至不需要更改操作类来完成此操作.