【问题标题】:Struts 2.3 Upgrading OGNL IssueStruts 2.3 升级 OGNL 问题
【发布时间】:2012-07-18 14:39:55
【问题描述】:

我有一个最初使用 Struts 2.0 构建的网站。我现在将它升级到 Struts 2.3。该网站包含执行 AJAX 请求的文件(基于通用搜索表单搜索库存)。 AJAX 请求将整个表单提交给 searchInventory 操作。这在 Struts 2.0 中运行良好,但在 2.3 中,我在错误日志中得到如下所示的异常:

[STDOUT] WARN [com.opensymphony.xwork2.ognl.OgnlValueStack] - CommonsLogger.warn(60) | Error setting expression 'nonInventoryRelatedField' with value '[Ljava.lang.String;@833d35'
ognl.OgnlException: target is null for setProperty(null, "9", [Ljava.lang.String;@833d35)
    at ognl.OgnlRuntime.setProperty(OgnlRuntime.java:2309)
    at ognl.ASTProperty.setValueBody(ASTProperty.java:127)
    at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
    at ognl.SimpleNode.setValue(SimpleNode.java:301)
    at ognl.ASTChain.setValueBody(ASTChain.java:227)
    at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
    at ognl.SimpleNode.setValue(SimpleNode.java:301)
    at ognl.Ognl.setValue(Ognl.java:737)
    at com.opensymphony.xwork2.ognl.OgnlUtil.setValue(OgnlUtil.java:217)
    at com.opensymphony.xwork2.ognl.OgnlValueStack.trySetValue(OgnlValueStack.java:186)
    at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:173)
    at com.opensymphony.xwork2.ognl.OgnlValueStack.setParameter(OgnlValueStack.java:151)
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.setParameters(ParametersInterceptor.java:292)
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:203)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:192)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at com.opensymphony.xwork2.interceptor.LoggingInterceptor.intercept(LoggingInterceptor.java:67)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at com.opensymphony.xwork2.interceptor.TimerInterceptor.intercept(TimerInterceptor.java:120)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
    at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:511)
    at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:432)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:399)
    at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
    at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:411)
    at org.springframework.security.ui.SessionFixationProtectionFilter.doFilterHttp(SessionFixationProtectionFilter.java:67)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:411)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:411)
    at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:411)
    at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:411)
    at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:278)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:411)
    at org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:411)
    at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:411)
    at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:188)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:236)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
    at java.lang.Thread.run(Thread.java:662)

问题在于包含库存搜索的页面有几个与库存搜索无关的其他字段(并且在inventorySearch 操作中没有getter/setter)。在 Struts 2.0 中,inventorySearch 操作会忽略这些额外的字段。但是,当这些额外的字段与表单一起发布时,Struts 2.3 会引发上述异常。有没有人对如何最好地解决这个问题有什么好主意?

我已经想到了以下选项:

  1. 查找包含库存搜索的所有页面以及每个页面中的所有额外字段。然后获取所有这些额外字段,并在库存搜索操作中为它们添加一个 getter/setter。
  2. 尝试重新设计库存搜索 AJAX 以不提交表单,而是使用 DOM 操作来检索所有与库存相关的字段并省略其他字段。
  3. 更改我的日志记录设置以抑制 OgnlExceptions。

是否有任何其他好的想法或论据支持/反对上述选择?

谢谢

【问题讨论】:

  • +1 过去我做过#3,但我很想知道其他人的建议。前两个选项太具有侵略性了。
  • 这是一个关于 OGNL 抛出的同一组警告的邮件列表中的长期讨论,其中大多数人倾向于调整日志级别以抑制警告。
  • 是的,我也遇到了这个问题,并更改了生产日志记录,但将其留给了开发人员。真的是无害的。
  • 能否请人指导我到哪里可以抑制 OGNL 异常?顺便提一句。 它们被写入 STDOUT,当您不想自己构建 OGNL 时,这会让人有点难以抑制。有帮手吗?
  • 严重吗?抑制警告是我们最好的做法吗?是否有某种方法可以过滤掉操作不关心的参数(即 ParameterNameAware 可能)?

标签: struts2


【解决方案1】:

我们在这里也有同样的事情。这是一个例外,但日志记录级别设置为警告。

当系统实际上想要警告你时,出现这么长的异常有点烦人。

Struts 2.3.x 想要的是提高人们对事物的认识。

您可以选择将日志记录级别提高到 ERROR,这样警告就不会总是出现并且会使您的生产日志文件膨胀。至少我们是这样做的。

例如,如果您使用的是 log4j.xml,您可以添加以下内容:

<logger name="com.opensymphony.xwork2.ognl.OgnlValueStack" additivity="false">
    <level value="ERROR" />
<appender-ref ref="LOGFILE" />
</logger>

稍后在您的开发环境中,您仍然可以启用该日志记录并逐步将您的操作类中缺少的属性与您的 OGNL 值堆栈使用情况相匹配。

【讨论】:

    猜你喜欢
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    相关资源
    最近更新 更多