【问题标题】:Struts2 Convention Plugin @Actions not mapping with Spring BootStruts2 Convention Plugin @Actions 不与 Spring Boot 映射
【发布时间】:2020-01-24 10:47:25
【问题描述】:

当升级我的应用程序以使用 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 {

}

更新

【问题讨论】:

  • @Roman C:该帖子中提到的依赖项都存在(请参阅更新)
  • @cID 你有进步吗?我尝试将 Struts 核心和插件降级到 2.3.37,但无济于事:我仍然无法摆脱 struts.xml。
  • 此外,如果您将应用程序打包为 WAR 并将其部署在外部 Tomcat 中,则它可以在没有 struts.xml 的情况下正常工作。
  • @Marc Tarin;不走运,我尝试了许多 struts2-convention-plugin 和 spring 版本的组合,扫描时似乎没有任何效果

标签: java spring-boot struts2 struts2-convention-plugin


【解决方案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 plugin 是必需的:

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

注意事项:

  • struts.xml 中定义的常量也可以迁移到 struts.properties 文件(列出的默认值here
  • struts.xml 优先于 Convention 插件和 struts.properties

当 struts.xml 被删除时,Convention 插件接管并使用包和类的名称映射 Action 类。借助一组 annotations,也可以覆盖默认约定(操作到 URL 映射、结果路径...)。

不过,正如 OP 所述,通过注释进行配置不能在嵌入式 Tomcat 中开箱即用(不过,它适用于外部 Tomcat)。

到目前为止,我能做的最好的事情是使用 embedded Jetty 而不是 Tomcat 使其工作,并将 recommended configuration 添加到 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 或更高版本,以防止出现类似于 的错误p>

    ERROR org.apache.struts2.convention.DefaultClassFinder.<init>:95 - Unable to read class [...]
    

【讨论】:

    【解决方案2】:

    通过spring2-convention-pluginPackageBasedActionConfigBuilder 有一个方法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" />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 2019-11-25
      相关资源
      最近更新 更多