Глобальные результаты с Struts 2 и плагином конвенции
Я хотел бы иметь некоторые глобальные результаты в моем приложении. В старой доброй конфигурации 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
,
3 ответа
К сожалению, вы не можете определить Result
или же Results
аннотация на пакет с использованием соглашения плагин. Вы должны определить глобальные результаты в конфигурации xml, и они не игнорируются, потому что конфигурация среды выполнения определяется независимо от того, какого поставщика конфигурации вы используете. Обходной путь должен определить Result
или же Results
на базовом классе.
Вы определяете global-result
в пакете. Такие результаты (глобальные) являются глобальными только для пакета, в котором они определены. Так что только те, actions
которые также объявлены в том же пакете, могут получить доступ к этим global-result
s. Перед вами два варианта:
Конфигурация 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
s. Чтобы достичь этого, ваш класс 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
). Просто добавьте этот постоянный элемент в ваш struts.xml (внутри <struts>
) и у тебя все будет хорошо
<constant name="struts.convention.default.parent.package" value="my-package"/>
Вот полезная ссылка о @ParentPackage
:
Хорошо относительно: Документация к плагину конвенции:
Начиная с 2.1.7, глобальные результаты (определенные на уровне класса), определенные с помощью аннотаций, будут наследоваться.
Так что для меня это звучит так, как, например, у меня может быть базовое действие, которое расширяет все мои действия, и тогда у меня получается глобальный результат. Другой идеей был пакет-info.java.
В той же документации сказано:
Плагин Convention позволяет классам действий определять различные результаты для действия. Результаты делятся на две категории, глобальные и локальные. Глобальные результаты являются общими для всех действий, определенных в классе действий. Эти результаты определяются как аннотации к классу действий. Локальные результаты применяются только к методу действия, для которого они определены. Вот пример различных типов аннотаций результатов
Так что я думаю, что они отличаются от стандартного локального результата и глобального результата.
Стандартные стойки:
- Глобальный результат виден каждому действию / перехватчику, определенному в пакете;
- Локальный результат виден только этому действию (но всем методам, если он вызывается с помощью динамического вызова метода);
- Локальный результат виден только этим Action и Method, если метод включен в тег Action в struts.xml (тогда у вас будет несколько тегов action для одного и того же класса Action и разных методов).
Я думаю, что с Convention, Global - это (2.), а Local - (3.) Они оба локальны для Action, но global могут возвращаться из каждого метода, а local - только из конкретного метода, который его определил.