2

When upgrading my application to use Spring Boot version 2.1.8.RELEASE + struts2-convention-plugin with Struts2-core version 2.5.20 the actions are not being mapped correctly and I am getting the error

com.opensymphony.xwork2.config.ConfigurationException: There is no Action mapped for namespace [/] and action name [home] associated with context path [].

If I decalre the actions in struts.xml they work perfectly.

Below is my current configuration, why are they not mapping?

I have tried many diffrent configs and nothing seems to work, the StrutsPrepareAndExecuteFilter is firing but not actions are found, as if Spring has not scanned them. Could this be a dependency version issue?

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>

Controller

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

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

Main

@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 Filter

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

}

UPDATE

Dependencies

4

2 回答 2

1

逐步完成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" />
于 2019-10-04T14:00:05.680 回答
1

经过几天的试验和错误,这里有一些线索。

Spring Boot 2.1.8 和配置了 struts.xml 的 Struts 2.5.20 可以工作。您的项目 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 类配置您的操作,需要Convention 插件

<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 插件接管并使用包和类的名称映射 Action 类。由于一组注释,默认约定(操作到 URL 的映射、结果路径...)也可以被覆盖。

尽管如此,正如 OP 所提到的,通过注释进行的配置在嵌入式 Tomcat 中无法开箱即用(尽管它与外部 Tomcat 一起使用)。

到目前为止我能做的最好的事情是使用嵌入式 Jetty而不是 Tomcat 使其工作,并将推荐的配置添加到 struts.properties:

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

启动日志仍然显示错误,但我能够访问配置的操作,而无需更多的 XML。

更新

OP更新后,我深入挖掘了一点。事实证明,Convention Plugin 可以很好地嵌入 Tomcat 并且不需要 XML,通过执行以下操作:

  • 将以下行添加到 struts.properties

    struts.convention.exclude.parentClassLoader=false
    
  • 将asm模块asmasm-commonsasm-tree升级到 6.2 或更高版本,以防止出现类似于

    ERROR org.apache.struts2.convention.DefaultClassFinder.<init>:95 - Unable to read class [...]
    
于 2019-10-04T14:09:36.940 回答