Плагин Struts2 Convention @ Действия, не отображаемые с помощью Spring Boot

При обновлении моего приложения для использования Spring Boot версии 2.1.8.RELEASE + struts2-Convention-plugin с Struts2-core версии 2.5.20 действия отображаются неправильно и Я получаю сообщение об ошибке

com.opensymphony.xwork2.config.ConfigurationException: Действие не сопоставлено для пространства имен [/] и имени действия [home], связанных с путем контекста [].

Если я декалирую действия в struts.xml, они работают отлично.

Ниже моя текущая конфигурация, почему они не отображаются?

Я пробовал много разных конфигураций, и ничего не работает, StrutsPrepareAndExecuteFilter запускается, но действия не обнаруживаются, как будто Spring их не сканировал. Может ли это быть проблемой версии зависимости?

application.yaml

  server:
    port: 8080
    servlet:
      context-path: /

Struts2.xml

    <struts>
        <constant name="struts.devMode" value="false" />
        <constant name="struts.convention.action.packages" value="com.myactions.action" />
        <constant name="struts.convention.action.includeJars" value=".*?/myjar.*?jar(!/)?,.*?/myjar*?jar(!/)?" />
        <constant name="struts.objectFactory" value="spring" />
        <constant name="struts.objectFactory.spring.autoWire" value="name" />
        <constant name="struts.multipart.maxSize" value="100000000" />
        <constant name="struts.convention.default.parent.package" value="struts-default"/>

    ## THIS WORKS
    <!--    <package name="home"  extends="struts-default">-->
    <!--        <action name="actionHome" class="com.myactions.action.HomeController" method="actionHome">-->
    <!--            <result name="success">home.jsp</result>-->
    <!--        </action>-->
    <!--    </package>-->

    </struts>

Контроллер

@Namespace("/")
public class HomeController extends BaseController {

    @Action("home")
    public String actionHome() throws Exception {           
        return SUCCESS;
    }   
}

Главная

@SpringBootApplication
@ServletComponentScan
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder springApplicationBuilder) {
        return springApplicationBuilder.sources(Application.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

Фильтр Struts2

@WebFilter("/*")
public class Struts2Filter extends StrutsPrepareAndExecuteFilter {

}

ОБНОВЛЕНИЕ

Зависимости


person clD    schedule 24.09.2019    source источник
comment
Вероятно, то же самое, что и stackoverflow.com/a/44890473/573032   -  person Roman C    schedule 28.09.2019
comment
@Roman C: все зависимости, упомянутые в этом посте, присутствуют (см. Обновление)   -  person clD    schedule 03.10.2019
comment
@cID добились ли вы прогресса? Я попытался понизить версию ядра и плагинов Struts до 2.3.37, но безрезультатно: я все еще не могу избавиться от struts.xml.   -  person Marc Tarin    schedule 04.10.2019
comment
Кроме того, он отлично работает без struts.xml, если вы упаковываете свое приложение как WAR и развертываете его во внешнем Tomcat.   -  person Marc Tarin    schedule 04.10.2019
comment
@Marc Tarin; Не повезло, я пробовал много комбинаций версий struts2-Convention-plugin и spring, при сканировании ничего не работает   -  person clD    schedule 04.10.2019
comment
Просто повезло со встроенной пристанью. Я отправлю ответ позже сегодня.   -  person Marc Tarin    schedule 04.10.2019
comment
@Marc Tarin: У меня есть объяснение, почему мои классы не сканировались, см. Обновление 2   -  person clD    schedule 04.10.2019
comment
Ответы следует добавлять как ответы, а не как часть вопроса. Новые вопросы должны быть новыми вопросами, а не добавляться к другим другим вопросам.   -  person Dave Newton    schedule 04.10.2019
comment
@cID Я видел ваше обновление, когда писал свой ответ. Угадайте что, наши результаты очень похожи;)   -  person Marc Tarin    schedule 04.10.2019


Ответы (2)


После пары дней проб и ошибок вот несколько подсказок.

Spring Boot 2.1.8 с Struts 2.5.20, настроенный с помощью struts.xml, работает. Для вашего проекта POM требуются как минимум следующие зависимости:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.1.8</version>
</dependency>
...
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>${struts2.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-spring-plugin</artifactId>
    <version>2.5.20</version>
</dependency>

Я также рекомендовал бы добавить Config Browser Plugin, чтобы легко перечислить доступные действия:

<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-config-browser-plugin</artifactId>
    <version>2.5.20</version>
</dependency>

Работает, когда вы упаковываете:

Чтобы избавиться от struts.xml и настроить свои действия только через классы Java, можно использовать подключаемый модуль конвенции. обязательный:

<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-convention-plugin</artifactId>
    <version>2.5.20</version>
</dependency>

Примечания :

  • константа, определенная в struts.xml, также может быть перенесена в файл struts.properties (значения по умолчанию перечислены в здесь)
  • struts.xml имеет приоритет над плагином Convention и struts.properties.

Когда struts.xml удаляется, подключаемый модуль Convention вступает во владение, и классы действий сопоставляются с использованием имен пакетов и классов. Соглашения по умолчанию (сопоставление действий с URL-адресами, путь к результату ...) также можно изменить с помощью набора аннотации.

Тем не менее, как упоминалось в OP, конфигурация с помощью аннотаций НЕ работает из коробки со встроенным Tomcat (хотя и с внешним Tomcat).

Лучшее, что я мог сделать до сих пор, это заставить его работать с помощью встроенный Jetty вместо Tomcat и добавление рекомендуемая конфигурация для struts.properties:

struts.convention.exclude.parentClassLoader=false
struts.convention.action.fileProtocols=jar,code-source

В стартовом журнале по-прежнему отображаются ошибки, но я могу получить доступ к настроенным действиям без XML.

ОБНОВЛЕНИЕ

После обновления OP я еще немного покопался. Оказывается, подключаемый модуль Convention отлично работает со встроенным Tomcat и не требует XML, выполнив следующие действия:

  • Добавление следующей строки в struts.properties

    struts.convention.exclude.parentClassLoader=false
    
  • Обновление модулей asm asm, asm -commons и asm-tree для выпуска 6.2 или новее, чтобы предотвратить ошибки, подобные

    ERROR org.apache.struts2.convention.DefaultClassFinder.<init>:95 - Unable to read class [...]
    
person Marc Tarin    schedule 04.10.2019

Пройдя через spring2-convention-plugin класс PackageBasedActionConfigBuilder имеет метод buildUrlSet, который получает все urls в классы, которые нужно сканировать на Actions, это удаляло urls из моих классов, и, следовательно, ничего не сканировалось.

Есть условие excludeParentClassLoader, которое необходимо установить в false (строка 415).

Решение

Установить ниже константы -

<constant name="struts.convention.exclude.parentClassLoader" value="false" />
<constant name="struts.convention.action.fileProtocols" value="jar,code-source" />
person clD    schedule 04.10.2019