2

简而言之,我有一个带有名为 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 方式没有问题。问题是我如何使用注释来做到这一点,因为带注释的参数需要常量表达式(实例变量 bestTutorialSite 不是常量表达式)。

更多信息:success.jsp

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

1 回答 1

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 约定插件。有关更多示例和参考,请参阅:http ://struts.apache.org/2.2.3/docs/convention-plugin.html#ConventionPlugin-Actionannotation

编辑:在解决评论中提出的动作名称问题。

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

动作获取教程可能有一个动作类。根据您的 xml,动作类必须位于根命名空间中。但是,当前的命名空间org.tutorial.struts2.action.TutorialAction不会在默认命名空间中,因为约定将搜索带有struts2action的包,并且层次结构更下方的包被解释为 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 和速度视图)。您还可以将结果的名称考虑到视图中,例如/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>

如果没有一个名为PersonInputor的类PersonInputAction(记住不必将Action放在最后),那么视图将按原样呈现,表单的视图将指向 Person Action,如下所示:

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

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

  • 重用视图
  • 采取行动后,使用 redirectAction 将您放回某个地方。也许更新后的列表。
  • 不太常见:使用不同的结果类型(json、流)

因此@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}"})
})

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

于 2013-02-11T06:20:10.193 回答