4

我有一个最初使用 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。

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

谢谢

4

1 回答 1

0

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

当系统实际上想要警告您时,有那么长的异常是有点烦人的。

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 值堆栈使用情况相匹配。

于 2012-11-16T02:36:33.123 回答