我想在我的应用程序中得到一些全局结果。在旧的XML配置中,它看起来像:
<global-results>
<result name="error" type="redirectAction">
<param name="actionName">index</param>
<param name="namespace">/</param>
</result>
</global-results>
但是当我使用约定插件时,XML 中的全局结果似乎被忽略了,那么我如何使用约定插件实现这一点呢?我不想让我的所有操作类都扩展定义了这些全局结果的自定义类。我认为package-info.java
应该是我的朋友,但我所能定义的与结果有关的东西就是@org.apache.struts2.convention.annotation.ResultPath
。
只是为了澄清:我不想避免struts.xml
配置 - 我只是想有一些工作的全局转发,所以如果任何操作出错,我想将用户转发到中央错误页面。这目前不适用于我的配置。如果您在我的struts.xml
或操作中看到问题并可以帮助我解决它,那就完全没问题了。
也许struts.xml
中的顺序很重要?这是我struts.xml
的结构:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="false" />
<constant name="struts.convention.result.path" value="/content/"/>
<constant name="struts.convention.default.parent.package" value="my-package"/>
<constant name="struts.convention.package.locators.disable" value="true"/>
<constant name="struts.convention.action.packages" value="..."/>
<constant name="struts.custom.i18n.resources" value="global" />
<constant name="struts.multipart.maxSize" value="10485760" />
<package name="my-package" extends="struts-default,json-default" namespace="/">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
</result-types>
<interceptors>
<interceptor name="login" class="loginInterceptor" />
<interceptor name="pagetitle" class="pagetitleInterceptor"></interceptor>
<interceptor-stack name="secureStack">
...
</interceptor-stack>
<interceptor-stack name="insecureStack">
...
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="secureStack" />
<global-results>
<result name="error" type="redirectAction">
<param name="actionName">index</param>
<param name="namespace">/</param>
</result>
</global-results>
</package>
</struts>
在我的行动中,我有:
public class MyActionClass extends ActionSupport {
@Actions({ @Action(value = "my-action", results = { @Result(name = "success", type = "tiles", location = "my.location") }) })
public final String myAction() throws Exception {
return ERROR;
}
}
当然,myAction
有更多的功能 - 这只是为了说明。执行操作时,它会在不使用瓷砖的情况下转发到my-action.jsp
,但我希望它会转发到/index.action
。
您无法使用约定插件在包上定义Result
或Results
注释。您必须在 xml 配置中定义全局结果,并且不会忽略它们,因为无论您使用哪个配置提供程序,都会定义运行时配置。解决方法是在基类上定义Result
或Results
。
您正在包中定义global-result
。这些类型的结果(全局(仅对它们在其中定义的包是全局的。因此,只有那些也在同一包中声明的actions
才能访问这些global-result
。您面前有两个选择:
XML 配置:
在XML配置中如何做到这一点是非常明显的(您只需在同一个包中定义它们(:
<package name="my-package" extends="struts-default,json-default" namespace="/">
<!-- This result is local to this action -->
<action name="someAction"class="com.example.SomeAction" method="execute">
<result name="someLocalResult">/localResult.jsp</result>
</action>
.
.
.
<global-results>
<!--This result is global **to the actions in my-package** -->
<result name="error" type="redirectAction">
<param name="actionName">index</param>
<param name="namespace">/</param>
</result>
</global-results>
</package>
<小时 />约定插件:
因此,如果您使用约定插件仅将 java 类标记为 actions
,则您没有为它们定义一个包(它们将属于默认包(。为此,您可以使用注释@ParentPackage
告诉框架此action
属于此包,并且可以使用它global-result
。为了实现这一点,你的Java类应该看起来像这样:
@ParentPackage(value="my-pacakge")
public class MyActionClass extends ActionSupport {
@Actions({ @Action(value = "my-action", results = { @Result(name = "success", type = "tiles", location = "my.location") }) })
public final String myAction() throws Exception {
return ERROR;
}
}
您的struts.xml
将保持不变:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="my-package" extends="struts-default,json-default" namespace="/">
.
.
.
<global-results>
<result name="error" type="redirectAction">
<param name="actionName">index</param>
<param name="namespace">/</param>
</result>
</global-results>
</package>
</struts>
摆脱设置每个动作@ParentPackage
的类似替代解决方案是将动作默认 pacakge 设置为您喜欢的包(此处为包含global-result
的包(。只需将这个常量元素添加到您的支柱中.xml(在<struts>
内部(,您就会没事:
<constant name="struts.convention.default.parent.package" value="my-package"/>
<小时 />这是一个关于@ParentPackage
的有用链接:
- @ParentPackage 来自 Apache 的注释
关于:公约插件文档:
所以在我看来,例如,我可以有一个基本动作,我从 2.1.7 开始,使用注释定义的全局结果(在类级别定义(将被继承。
的所有动作都会扩展,然后我有一个全局结果。另一个想法是包信息.java。
同样的文档说:
约定插件允许操作类为操作定义不同的结果。 结果分为两类,全局和局部。全局结果在操作类中定义的所有操作之间共享。这些结果定义为操作类上的批注。本地结果仅适用于定义它们的操作方法。以下是不同类型的结果注释的示例
所以我认为它们与标准的局部结果和全局结果是不同的概念。
标准支柱:
- 全局结果对包中定义的每个操作/拦截器可见;
- 本地结果仅对该操作可见(但如果使用动态方法调用调用,则对所有方法可见(;
- 如果该方法包含在 struts 中的 Action 标记中,则本地结果仅对该操作和方法可见.xml则同一 Action 类和不同方法将有多个操作标记(。
我认为对于惯例,全局是(2.(,本地是(3(。它们都是 Action 的本地,但全局可以从每个方法返回,而全局只能从定义它的特定方法返回。