Глобальные результаты с 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.


person LordHelmchen    schedule 26.09.2013    source источник
comment
stackoverflow.com/a/16934584/1654265   -  person Andrea Ligios    schedule 27.09.2013
comment
извините, я не вижу связи с моим вопросом, единственное, что я нашел, это утверждение: использование плагина Convention не означает, что у вас нет struts.xml; это означает, что... когда какая-то конфигурация struts не связана с действием... вы абсолютно можете использовать struts.xml   -  person LordHelmchen    schedule 27.09.2013
comment
да. Другой вопрос начинается с противоположной точки зрения: вы говорите (как) Могу ли я избежать использования struts.xml для глобальных результатов с помощью подключаемого модуля Convention?, в то время как в связанном вопросе говорилось (как) можно ли использовать struts.xml для получения глобальных результатов с подключаемым модулем Convention?. Но ответ тот же: Convention Plugin или нет, глобальные результаты (можно и) нужно помещать в struts.xml. Это правильно, если подумать: в какое действие следует поместить глобальный результат?   -  person Andrea Ligios    schedule 27.09.2013
comment
Что касается: Документация по подключаемому модулю конвенции: Начиная с версии 2.1.7, глобальные результаты (определенные на уровне класса), определенные с помощью аннотаций, будут наследоваться. Так что мне кажется, что я могу, например, иметь базовое действие, которое все мои действия расширить, и тогда у меня есть глобальный результат. Другой идеей был package-info.java.   -  person LordHelmchen    schedule 27.09.2013
comment
Я думаю, что это уже есть в моем вопросе: Я не хочу, чтобы все мои классы действий расширяли пользовательский класс, в котором определены эти глобальные результаты;)   -  person LordHelmchen    schedule 27.09.2013
comment
ОТД 2.1? Какую версию Struts2 вы используете? Какая ошибка выдается вам сейчас при перенаправлении на ERROR? Будет ли это работать, если вместо redirectAction вы вернете error.jsp из результата ошибки? Вы уверены, что не ссылаетесь циклически на действие index в неправильном стеке Interceptor? (Interceptor Stack обнаруживает, что вы не вошли в систему —> возвращает ошибку —> перенаправляет на индекс —> Interceptor Stack обнаруживает, что вы не вошли в систему —> возвращает ошибку —> перенаправляет на индекс ...)   -  person Andrea Ligios    schedule 27.09.2013
comment
...обновил Struts (до 2.3), но забыл про DTD - исправил. К сожалению, ошибки нет. Когда действие выполняется, оно перенаправляется на my-action.jsp, оно игнорирует глобальную пересылку из struts.xml — даже когда я использую несуществующее имя действия, ошибки нет. просто проигнорил.   -  person LordHelmchen    schedule 27.09.2013


Ответы (3)


К сожалению, вы не можете определить аннотацию Result или Results для пакета с помощью плагина соглашения. Вы должны определить глобальные результаты в конфигурации XML, и они не игнорируются, поскольку конфигурация времени выполнения определяется независимо от того, какой поставщик конфигурации вы используете. Обходной путь — определить Result или Results в базовом классе.

person Roman C    schedule 26.09.2013

Вы определяете 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-results. Для этого ваш 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 состоит в том, чтобы установить пакет действий по умолчанию для вашего любимого пакета (здесь пакет, содержащий global-result). Просто добавьте этот постоянный элемент в свой struts.xml (внутри <struts>), и все будет в порядке:

<constant name="struts.convention.default.parent.package" value="my-package"/>

Вот полезная ссылка про @ParentPackage:

  1. аннотация @ParentPackage от apache
person Amir Qasemi    schedule 22.08.2016

Что касается: Документация по подключаемому модулю конвенции:

Начиная с версии 2.1.7, глобальные результаты (определенные на уровне класса), определенные с помощью аннотаций, будут наследоваться.

Так что мне кажется, что я могу, например, иметь базовое действие, которое расширяет все мои действия, а затем у меня есть глобальный результат. Другой идеей был package-info.java.

В той же документации сказано:

Плагин Convention позволяет классам действий определять разные результаты действия. Результаты делятся на две категории: глобальные и локальные. Глобальные результаты являются общими для всех действий, определенных в классе действий. Эти результаты определяются как аннотации к классу действий. Локальные результаты применяются только к тому методу действия, для которого они определены. Вот пример различных типов аннотаций результатов.

Так что я думаю, что они отличаются от стандартных Local Result и Global Result.

Стандартные стойки:

  1. Глобальный результат виден каждому действию/перехватчику, определенному в пакете;
  2. Локальный результат виден только этому действию (но всем методам, если они вызываются с помощью динамического вызова метода);
  3. Локальный результат виден только для этого действия и метода, если метод включен в тег действия в struts.xml (тогда у вас будет несколько тегов действия для одного и того же класса действий и разных методов).

Я думаю, что с соглашением глобальный (2.) и локальный (3.) Они оба локальны для действия, но глобальный возвращается из каждого метода, а локальный - только из конкретного метода, который его определил.

person Andrea Ligios    schedule 27.09.2013
comment
я полностью с вами, но, к сожалению, я не понимаю, как это может помочь мне с моей проблемой иметь одну глобальную переадресацию, которую я могу использовать в разных классах действий. - person LordHelmchen; 27.09.2013
comment
Не всегда ответ может быть таким. Это ответ, который вы НЕ МОЖЕТЕ сделать, который (если не доказано, что он неверен) идеально отвечает на вопрос. Обратите внимание, что даже базовое действие, расширенное всеми действиями с глобальным результатом, не сделает этот результат действительно глобальным результатом Struts2, он будет локально глобальным результатом для всех действий, которые расширяют базовый результат. Ни один перехватчик или действия, не расширяющие базу, не смогут получить к ней доступ. Затем используйте struts.xml. Кстати, для опыта, глобальные результаты максимум 3-4 для проекта, иначе что-то не так (или особенное)... - person Andrea Ligios; 27.09.2013
comment
По крайней мере, теперь мы знаем, почему в документации плагина Конвенции говорится о глобальных аннотированных результатах и ​​что они из себя представляют. - person Andrea Ligios; 27.09.2013
comment
Вы написали Тогда используйте struts.xml. это именно то, что я пробовал, но у меня это не сработало (см. мой обновленный вопрос). И вы правы насчет количества глобальных результатов - у меня их ровно 3 в моем проекте;) - person LordHelmchen; 27.09.2013