I am trying to upgrade a project from struts 2.2.3 to struts 2.3.15.1. After bumping the version the application is working but every time I submit a page it is throwing a horrendously long warning in the log. It appears that the ParametersInterceptor is trying to set a property in my class named "action:PersonalInfo_next" which is the name of the submit button form element. This name is created by struts but when the form comes back it is treating it like a standard form field and trying to save it for me.
I have tried adding action:.* to the excludeParams option in struts.xml but it seems to have no effect:
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,action:.*</param>
</interceptor-ref>
The warning is as follows:
10/09/13 15:16:18,939 DEBUG [ com.opensymphony.xwork2.interceptor.ParametersInterceptor ]: Parameter [action:PersonalInfo_next] didn't match acceptedPattern pattern!
10/09/13 15:16:18,939 WARN [ com.opensymphony.xwork2.ognl.OgnlValueStack ]: Error setting expression 'action:PersonalInfo_next' with value '[Ljava.lang.String;@47773'
ognl.ExpressionSyntaxException: Malformed OGNL expression: action:PersonalInfo_next [ognl.ParseException: Encountered " ":" ": "" at line 1, column 7.
Was expecting one of:
<EOF>
"," ...
"=" ...
"?" ...
"||" ...
"or" ...
"&&" ...
"and" ...
[snip]
at ognl.Ognl.parseExpression(Ognl.java:112)
at com.opensymphony.xwork2.ognl.OgnlUtil.compile(OgnlUtil.java:268)
at com.opensymphony.xwork2.ognl.OgnlUtil.setValue(OgnlUtil.java:230)
at com.opensymphony.xwork2.ognl.OgnlValueStack.trySetValue(OgnlValueStack.java:183)
at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:170)
at com.opensymphony.xwork2.ognl.OgnlValueStack.setParameter(OgnlValueStack.java:148)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.setParameters(ParametersInterceptor.java:318)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:231)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
[snip]
Caused by: ognl.ParseException: Encountered " ":" ": "" at line 1, column 7.
Was expecting one of:
<EOF>
"," ...
"=" ...
"?" ...
[...]
There ends up being over 300 lines of this on every submit.
At first glance I thought it might be related to this issue but it happens when devMode is explicitly disabled. Since it is a warning and the application is working, I also toyed with the idea of just ignoring this via log4j configuration but it looks like most of it is being printed directly to stdout or stderr so that isn't an option either.
For reference, here is the relevant action element in my struts.xml:
<action name="PersonalInfo_*" class="project.web.actions.EditPersonalInfo" method="{1}">
<interceptor-ref name="defaultStack">
<param name="store.operationMode">AUTOMATIC</param>
</interceptor-ref>
<result name="input">/jsp/personalInfo.jsp</result>
<result name="next" type="redirectAction">
<param name="parse">true</param>
<param name="actionName">Address_open</param>
<param name="namespace">/</param>
<param name="id">${id}</param>
</result>
</action>
Also the form and submit elements from the JSP: (the JSP is quite large)
<s:form action="PersonalInfo_personalInfo" namespace="/" id="appForm" cssClass="form personal_info" autocomplete="off">
[lots of fields]
<s:submit value="Next" cssClass="ksu-button" action="PersonalInfo_next"/>
It turns out we had some customizations going on in our stack that were throwing a wrench into the gears. This was in some older common code that someone in our organization wrote years ago.
The base action class that all of my actions extend was a class that extended com.opensymphony.xwork2.ActionSupport and implemented the com.opensymphony.xwork2.interceptor.ParameterNameAware interface which means it had an acceptableParameterName method which looked like this:
public boolean acceptableParameterName(String parameterName) {
return prepareInvoked || getPreprepareParams().contains(parameterName);
}
That getPrepareaParams method returned a list that had as its only entry "id" and the prepareInvoked gets set to true when prepare() is called for the first time.
Our stack calls the params interceptor twice. The first time through it only processed the "id" parameter. The second time through, the acceptableParameterName method always returned true. I'm not sure what the intended functionality of this was. My best guess is that it was an attempt to optimize something and was probably targeted at some other application that is using this common code.
But the unintended side effect of this method after the upgrade was that the default excludeParams as well as the explicit excludeParams setting in my struts.xml were both ignored.
I have removed this method from the base class and things seem to be working. There is now a single DEBUG line from the params interceptor:
DEBUG [ com.opensymphony.xwork2.interceptor.ParametersInterceptor ]: Parameter [action:PersonalInfo_next] didn't match acceptedPattern pattern!
Compared to the 300+ lines of warning I was getting before, this is downright acceptable!