从 Struts 2.3.12 迁移到 2.3.20 后,动作映射不起作用

S P*_*day 5 java struts2 upgrade dmi action-mapping

目前我在我的项目中使用 Struts 2.3.12,一切正常。现在我需要将 Struts 版本升级到 2.3.20 以解决一些安全问题。

我在我的项目中将 Struts 和所需的 Struts 插件版本更改为 2.3.20pom.xml并构建项目战争。现在,我正在尝试访问我的应用程序主页 URL,然后出现以下异常:

没有为与上下文路径关联的命名空间[/web/public]和操作名称映射的操作。- [未知地点][reset-password!reset][/ims]

com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:185)
org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:37)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:554)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
org.josso.tc55.agent.SSOAgentValve.invoke(SSOAgentValve.java:472)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:875)
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
java.lang.Thread.run(Thread.java:662)
Run Code Online (Sandbox Code Playgroud)

我对正在发生的事情一无所知。

我查看了 struts 2.3.20 的发行说明,但没有得到任何提示。

我正在使用strust2-convention-plugin.

我正在分享我的web.xmlstruts.xml文件。它看起来如下所示:

web.xml

com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:185)
org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:37)
com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:554)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
org.josso.tc55.agent.SSOAgentValve.invoke(SSOAgentValve.java:472)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:875)
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
java.lang.Thread.run(Thread.java:662)
Run Code Online (Sandbox Code Playgroud)

struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="jail" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>ims</display-name>

    <!-- JCaptcha servlet mapping -->
    <servlet>
        <servlet-name>jcaptcha</servlet-name>
        <servlet-class>com.sapienza.jail.controller.jcaptcha.JailImageCaptchaServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>jcaptcha</servlet-name>
        <url-pattern>/web/public/jcaptcha.jpg</url-pattern>
    </servlet-mapping>
    
    <!-- Filters -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/web/*</url-pattern>
    </filter-mapping>
    
    <filter>
        <filter-name>ResponseOverrideFilter</filter-name>
        <filter-class>org.displaytag.filter.ResponseOverrideFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ResponseOverrideFilter</filter-name>
        <url-pattern>/web/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/web/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/web/public/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/struts/*</url-pattern>
    </filter-mapping>

    <!-- JSP configuration -->
    <jsp-config>
        <jsp-property-group>
            <url-pattern>*.jsp</url-pattern>
            <el-ignored>false</el-ignored>
            <page-encoding>UTF-8</page-encoding>
            <include-prelude>/jsp/common/taglibs.jspf</include-prelude>
        </jsp-property-group>
    </jsp-config>
    <welcome-file-list>
        <welcome-file>/jsp/common/home.jsp</welcome-file>
    </welcome-file-list>

    <!-- Spring Listener -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <!-- Skin listener -->
    <listener>
        <listener-class>com.sapienza.jail.listener.ResourceListener</listener-class>
    </listener>

    <!-- LDAP Synchronisation Listeneer -->
    <listener>
        <listener-class>com.sapienza.jail.listener.LdapSyncListener</listener-class>
    </listener>

    <!-- Tiles listener -->
    <listener>
        <listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
    </listener>

    <context-param>
        <param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
        <param-value>/WEB-INF/tiles/skins-definitions.xml,/WEB-INF/tiles/pages-definitions.xml</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.tiles.evaluator.AttributeEvaluator</param-name>
        <param-value>org.apache.tiles.evaluator.el.ELAttributeEvaluator</param-value>
    </context-param>
    
</web-app>
Run Code Online (Sandbox Code Playgroud)

struts-base.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    
    <include file="struts-default.xml"/>
    
    <constant name="struts.objectFactory" value="spring"/>
    <constant name="struts.devMode" value="true"/>
    <constant name="struts.convention.default.parent.package" value="base-configuration"/>
    <constant name="struts.convention.classes.reload" value="true"/>
    <constant name="struts.enableJSONValidation" value="true"/>
    
    <!-- struts configuration common for the whole application -->
    <include file="struts-base.xml"/>
    
</struts>
Run Code Online (Sandbox Code Playgroud)

我在我的班级中使用基于注释的动作映射如下

<struts>

    <!-- This package is abstract. It is not mean to declare any actions, only 
        common components such as interceptors, global results ... -->
    <package name="base-configuration" abstract="true" extends="tiles-default">

        <result-types>
            <result-type name="jasper" class="org.apache.struts2.views.jasperreports.JasperReportsResult"/>
            <result-type name="json" class="org.apache.struts2.json.JSONResult"/>
            <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
        </result-types>

        <!-- create a custom paramsPrepareParamsStack using our log4j interceptor -->
        <interceptors>
            <!-- declaration of the custom interceptor using log4j to log exceptions. -->
            <interceptor name="log4jExceptionMappingInterceptor" class="log4jExceptionMappingInterceptor" />

            <!-- declaration of the custom security interceptor -->
            <interceptor name="securityInterceptor" class="securityInterceptor" />

            <!-- declaration of the custom SearchBean interceptor -->
            <interceptor name="searchBeanInterceptor" class="searchBeanInterceptor" />

            <!-- declaration of the custom WhiteSpaceTrim interceptor -->
            <interceptor name="whiteSpaceTrimmerInterceptor" class="whiteSpaceTrimmerInterceptor" />

            <!-- Struts2 JSON Validation -->
             <interceptor name="jsonValidation" class="org.apache.struts2.json.JSONValidationInterceptor" />

            <interceptor-stack name="imsDefaultStack">
                <!-- insert log4j interceptor inserted in the custom stack -->
                <interceptor-ref name="log4jExceptionMappingInterceptor" />
                <!-- insert the custom security interceptor -->
                <interceptor-ref name="securityInterceptor" />
                <interceptor-ref name="alias" />
                <interceptor-ref name="params" />
                <interceptor-ref name="servletConfig" />
                <interceptor-ref name="prepare" />
                <interceptor-ref name="i18n" />
                <interceptor-ref name="chain" />
                <interceptor-ref name="checkbox" />
                <interceptor-ref name="staticParams" />
                <interceptor-ref name="params" />
                <!-- excludes base CRUD methods from the validation process -->
                <!-- validation interceptor triggers the xml validation -->
                <interceptor-ref name="validation">
                    <param name="validateAnnotatedMethodOnly">true</param>
                    <param name="excludeMethods">input,back,cancel,list,view,initCreate,initUpdate,delete</param>
                </interceptor-ref>
                <!-- ajax validation interceptor -->
                <interceptor-ref name="jsonValidation">
                    <param name="excludeMethods">input</param>
                </interceptor-ref>
                <!-- workflow interceptor triggers programmatic validation (calls validate()) -->
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel,list,view,initCreate,initUpdate,delete</param>
                </interceptor-ref>
            </interceptor-stack>

            <!-- this new custom stack will be used for public URL -->
            <interceptor-stack name="imsNoSecurityStack">
                <!-- insert log4j interceptor inserted in the custom stack -->
                <interceptor-ref name="log4jExceptionMappingInterceptor" />
                <interceptor-ref name="alias" />
                <interceptor-ref name="params" />
                <interceptor-ref name="servletConfig" />
                <interceptor-ref name="prepare" />
                <interceptor-ref name="i18n" />
                <interceptor-ref name="chain" />
                <interceptor-ref name="checkbox" />
                <interceptor-ref name="staticParams" />
                <interceptor-ref name="params" />
                <!-- excludes base CRUD methods from the validation process -->
                <!-- validation interceptor triggers the xml validation -->
                <interceptor-ref name="validation">
                    <param name="validateAnnotatedMethodOnly">true</param>
                    <param name="excludeMethods">input,back,cancel,list,view,initCreate,initUpdate,delete</param>
                </interceptor-ref>
                <!-- ajax validation interceptor -->
                <interceptor-ref name="jsonValidation">
                    <param name="excludeMethods">input</param>
                </interceptor-ref>
                <!-- workflow interceptor triggers programmatic validation (calls validate()) -->
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel,list,view,initCreate,initUpdate,delete</param>
                </interceptor-ref>
            </interceptor-stack>
        </interceptors>

        <!-- the new custom stack will be the default one used in the sub packages. -->
        <default-interceptor-ref name="imsDefaultStack" />

        <!-- exception handling -->
        <global-results>
            <result name="error">/jsp/common/error.jsp</result>
            <result name="securityError">/jsp/common/access-denied.jsp</result>
            <result name="ldapError">/jsp/common/ldap-connection-error.jsp</result>
        </global-results>
        
        <!-- any unhandled exceptions will return the error page displaying the 
                message of the exception. -->
        <global-exception-mappings>
            <exception-mapping result="error" exception="java.lang.Exception" />
            <exception-mapping result="securityError" exception="com.sapienza.jail.exception.NoApplicationAccess" />
            <exception-mapping result="ldapError" exception="com.sapienza.jail.exception.LDAPConnectionException" />
        </global-exception-mappings>

    </package>

</struts>
Run Code Online (Sandbox Code Playgroud)

Rom*_*n C 0

由于版本更改,Struts 默认ActionMapper实现发生了显着变化。在此期间应用了许多安全修复程序。

您可以查看安全公告

问题在于您将DMI与 URL 映射一起使用。DMI 默认情况下处于关闭状态。DMI 功能可能无法在当前版本的 Struts 中运行,您应该更改操作的映射。

但在升级到 2.3.20 之前,您可以尝试升级到 2.3.16.3。

要打开 DMI,请尝试使用常量来启用它:

<constant name="struts.enable.DynamicMethodInvocation" value="true"/> 
Run Code Online (Sandbox Code Playgroud)