In the following action class, I'm using the parameters interceptor.
@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value = "struts-default")
@InterceptorRefs(@InterceptorRef(value="store", params={"operationMode", "AUTOMATIC"}))
public final class TestAction extends ActionSupport implements Serializable, ValidationAware, Preparable
{
private static final long serialVersionUID = 1L;
private String param1;
private String param2;
//Getters and setters.
public TestAction() {}
@Action(value = "TestMessage",
results = {
@Result(name=ActionSupport.SUCCESS, type="redirectAction", params={"namespace", "/admin_side", "actionName", "Test"}),
@Result(name = ActionSupport.INPUT, location = "Test.jsp")},
interceptorRefs={
@InterceptorRef(value="paramsPrepareParamsStack", params={"params.acceptParamNames", "param1, param2", "params.excludeParams", "extraParam", "validation.validateAnnotatedMethodOnly", "true"})
})
public String insert() {
// Do something. Add or update a row to the database (one at a time).
addActionMessage("Action message");
addActionError("Error message");
return ActionSupport.SUCCESS;
}
@Action(value = "Test",
results = {
@Result(name = ActionSupport.SUCCESS, location = "Test.jsp"),
@Result(name = ActionSupport.INPUT, location = "Test.jsp")},
interceptorRefs = {
@InterceptorRef(value = "paramsPrepareParamsStack", params = {"params.acceptParamNames", "param1, param2", "params.excludeParams", "extraParam", "validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
public String load() throws Exception {
// This method is just required to return an initial view on page load.
return ActionSupport.SUCCESS;
}
@Override
public void prepare() throws Exception {}
}
The following is <s:form>
:
<s:form namespace="/admin_side" action="Test" validate="true" id="dataForm" name="dataForm">
<s:if test="hasActionMessages()">
<s:actionmessage theme="jquery"/>
</s:if>
<s:if test="hasActionErrors()">
<s:actionerror theme="jquery"/>
</s:if>
<s:hidden name="param1"/>
<s:hidden name="param2"/>
<s:hidden name="extraParam"/>
<s:submit value="Submit" action="TestMessage"/>
</s:form>
Here, the hidden form field extraParam
is not declared and consequently, has no setter and getter in the action class.
In this case, the following message appears on the server terminal, when this form is submitted.
SEVERE: Developer Notification (set struts.devMode to false to disable this message): Unexpected Exception caught setting 'extraParam' on 'class actions.TestAction: Error setting expression 'extraParam' with value ['', ]
params.excludeParams
does not exclude the parameter extraParam
as in the action class.
Can we somehow prevent such exceptions while using the parameters interceptor. Such messages are unnecessarily added to action messages and displayed through <s:actionmessage/>
, if used, when they are not supposed to be shown at all.
If this paramsPrepareParamsStack
is replaced with defaultStack
in the action class then, such messages don't appear. It just gives a warning as follows.
WARNING: Parameter [extraParam] is on the excludeParams list of patterns!
Please don't just say, set struts.devMode
to false
to disable
such messages.
I've already said in the comment that interceptor parameters are not inherited by the interceptor configs of the parent packages if you define your own set of parameters that override the default settings. See Interceptor Parameter Overriding Inheritance.
There are also some techniques used to obtain two different maps of interceptor parameters, see Getting Interceptor Parameters in Struts2.
The convention plugin creates XWork package configs that inherited from some parent package. See my answer for Struts 2 Convention Plugin Define Multiple Parent Packages.
So, all you have to do is to override the default parameter set by the parent configuration if you want to add your own parameters to the set. Either interceptor
tag or interceptor-stack
tag and you should do it for each interceptor-ref
tag.
The convention plugin uses @InterceprorRef
annotation for the same purpose but with a caveat that if applied on the class, it applies on each action of that class. So, be careful when using this annotation on the class level. You are overriding the interceptor stack parameters, so you should use a prefix followed by dot of the interceptor name referenced in the stack for each parameter name, but this only works if you have unique names of the interceptor-ref
s in the stack.
If you have two references of the params
interceptor in the paramsPrepareParamsStack
then you can't override the second params
interceptor-ref
unless you create your own interceptor stack and specify parameter overrides on each reference of the interceptor.