Отображение действий не работает после перехода с Struts 2.3.12 на 2.3.20
В настоящее время я использую Struts 2.3.12 в своем проекте, и все работает нормально. Теперь у меня есть требование обновить версию Struts до 2.3.20 для решения некоторых проблем безопасности.
Я изменил версию Struts и необходимых плагинов для Struts на 2.3.20 в моем проекте и создал проектную войну. Теперь я пытаюсь получить доступ к домашней странице приложения, после чего получаю следующее исключение:
Для пространства имен нет сопоставленных действий
[/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)
Я не мог получить ни единой подсказки о том, что происходит; Я заглянул в примечание к выпуску стоек 2.3.20, но подсказок не получаю.
Я использую strust2-Convention-плагин.
Я делюсь своими файлами web.xml и struts.xml. Это выглядит следующим образом:
1. web.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>
2. struts.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>
3. struts-base.xml
<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>
Я использую аннотации на основе действий в своем классе, как показано ниже
@Results({
@Result(name="index", type="tiles", location="testPage"),
@Result(name = "redirect", location = "user/search-user!view", type = "redirectAction")
})
@Namespace("/web/public")
@Action
public class HomeAction extends BaseAction {
private static final Logger logger = Logger.getLogger(HomeAction.class);
private static final String SESSIONBASKET = "userSessionBasket";
//-------------------------------------------------------------------------
// Dependencies injected by spring via setters
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// Constructor and methods
//-------------------------------------------------------------------------
public HomeAction() {
}
@Override
public String execute() {
if (isInHttpSession(SESSIONBASKET)){
getSession().removeAttribute(SESSIONBASKET);
}
return result(REDIRECT_RESULT);
}
//-------------------------------------------------------------------------
// Getters and Setters
//-------------------------------------------------------------------------
}
3 ответа
Наконец, я нашел виновника, это было из-за конфликтующего asm jar, который дважды включается в версии (3.1 и 5.1) в моем приложении lib forder. После обновления до Struts 2.3.20 он загружал asm 5.1, а asm 3.1 был включен из родительского приложения pom.
Также вы должны явно включить DMI, добавив следующую константу в вашем struts.xml.
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
Некоторое время боролся с апгрейдами с 2.3.16 до 2.3.20. Не уверен, что мы столкнулись с той же проблемой, но, тем не менее, я разделяю решение, которое помогло мне.
Действия плагина REST, которые должны быть проиндексированы с помощью суффикса с использованием соглашений: например, struts.convention.action.suffix = Controller
После обновления всех файлов struts 2-* jar и xwork-core.jar не работал вообще
Ничего не было напечатано в журналах.
Наконец, наткнулся на этот пост: http://comments.gmane.org/gmane.comp.jakarta.struts.user/186383"У меня была такая же проблема сегодня утром после обновления только файлов JARS Struts 2 и XWAR. Я обновил Файлы jar asm, asm-commons, asm-tree и commons-lang3 к файлам, найденным в файле struts-2.3.20-lib.zip, и проблема исчезла."
После обновления asm-*. Jar проблемы исчезли.
Единственное, что я не мог понять, это то, что версия 2.3.20 понижает некоторые jar-файлы, такие как commons-validator, до 1.3.1 (с 1.4.0) и common-collection до 1.3.1 (с 3.2.1).
Надеюсь, это поможет вашим проектам.
ура
Так как версия была изменена, мапперы распорок значительно изменились. Много исправлений безопасности было применено во время этого. Вы можете проверить бюллетени по безопасности. Проблема в том, что вы используете DMI с отображением URL. DMI по умолчанию отключен. Функция DMI больше не может работать в будущих версиях Struts, и вы должны изменить отображение своего действия. Но до обновления до 2.3.20 вы можете попробовать 2.3.16.3. Чтобы включить DMI, попробуйте включить его, используя постоянную
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>