Struts2 - 使用Annotation将action成员变量作为参数传递

时间:2013-02-11 02:16:59

标签: struts2

简而言之,我有一个带有名为bestTutorialSite的实例变量的动作类。可以将此变量传递给JSP,如下所示:

<package name="tutorial1" namespace="/" extends="struts-default">
    <action name="getTutorial" class="org.tutorial.struts2.action.TutorialAction">
        <result name="success" type="redirectAction">
            <param name="actionName">getTutorialPage</param>
            <param name="namespace">/tutorials</param>
            <param name="message">${bestTutorialSite}</param>
        </result>
        <result name="error" type="redirectAction">
            <param name="actionName">getErrorPage</param>
            <param name="namespace">/tutorials</param>
            <param name="message">${bestTutorialSite}</param>
        </result>
    </action>
</package>

<package name="tutorial2" namespace="/tutorials" extends="struts-default">
    <action name="getTutorialPage">
        <result>/success.jsp</result>
    </action>
    <action name="getErrorPage">
        <result>/error.jsp</result>
    </action>
</package>

使用XML方式没问题。 问题是如何使用Annotation来实现这一点,因为带注释的params需要常量表达式(实例变量bestTutorialSite不是常量表达式)。

更多信息: 的success.jsp

<body>
  Success Page!!
<br/>
 <s:property value="$parameters['message']"/>
</body>

1 个答案:

答案 0 :(得分:3)

@Results({
   @Result(name = "success", type = "redirectAction", params = {"namespace", "/tutorials", "actionName", "getTutorialPage", "message", "${bestTutorialSite}"}),
   @Result(name = "error", type = "redirectAction", params = {"namespace", "/tutorials", "actionName", "getErrorPage", "message", "${bestTutorialSite}"})
})
public class TutorialAction extends ActionSupport...

注意:作为依赖项,您需要struts2 convention插件。 有关更多示例和参考,请参阅:http://struts.apache.org/2.2.3/docs/convention-plugin.html#ConventionPlugin-Actionannotation

修改: 在解决评论中提出的行动名称问题。

约定使用以连字符分隔的操作名称。那就是我们不会调用 getTutorial 的动作,而是 get-tutorial

动作 get-tutorial 可能有一个动作类。根据您的xml,操作类必须位于根命名空间中。但是,当前命名空间为org.tutorial.struts2.action.TutorialAction,这将不在默认命名空间中,因为约定将搜索包含 struts2 操作的包,并且层次结构中的包将被解释作为struts2包。

因此约定会将您的org.tutorial.struts2.action.TutorialAction类解释为位于/action/tutorial命名空间中。我们应该将包名称更改为org.tutorial.myapp.action.GetTutorialAction或类似的内容以避免此问题。

注意,Get已附加到 TutorialAction ,因此struts会将操作定位为/get-tutorial

视图遵循包名称的并行模式。当您的当前操作站立时,您需要将视图定位在/WEB-INF/content/action/tutorial.jsp(约定也可以通过文件扩展名识别freemarker和velocity视图)。您也可以将结果的名称考虑在视图中,例如/WEB-INF/content/action/tutorial-success.jsp/WEB-INF/content/action/tutorial-error.jsp/WEB-INF/content/action/tutorial-input.jsp,因此如果执行返回“成功”,您将获得前者,如果“错误“然后是后者。类名当然是驼峰式的(根据Java命名约定)但是视图将全部为小写,并且连字符将出现在单词之间。

一种非常有用的技术是将所有输入表单创建为“* -input.jsp”,您可以直接转到视图(绕过动作类),例如将锚定义为:

<s:a namespace="/employee" action="person-input">Go to Person Input</s:a>

如果没有名为PersonInputPersonInputAction的类(请记住不必将 Action 放在最后),那么视图将按原样渲染,表单的视图将指向Person Action,如下所示:。

如果表单的验证失败(返回输入),则Person操作将首先尝试“person-input”,然后您将返回表单。这非常有用。

使用约定时,注释的最大需求应该是:

  • 重复使用观点
  • 使用redirectAction在采取行动后让你回到某个地方。可能是更新后的列表。
  • 不太常见:使用不同的结果类型(json,stream)

因此@Result和@Results注释是最常见的。 @Action注释通常在您尝试降低约定时出现,但请记住,除了偏离预期之外,您不需要编写注释。所以你真的在为自己做工作。

动作注释的一个很好的用途是在同一个类中声明多个动作方法(对于单个实体的某些crud操作可能很有用)。我个人更喜欢每个动作策略一个类,但是可以理解动作注释的这种用法,但是正如提到的那样使用它来产生动作同义词或覆盖我不喜欢的约定。

除了“getTutorial”等惯例之外,您可以说:

@Action(value="/getTutorial", 
    results={
       @Result(name = "success", type = "redirectAction", params = {"namespace", "/tutorials", "actionName", "getTutorialPage", "message", "${bestTutorialSite}"}),
       @Result(name = "error", type = "redirectAction", params = {"namespace", "/tutorials", "actionName", "getErrorPage", "message", "${bestTutorialSite}"})
})

如上所述,不建议这样做。