I have a hidden field on every page inside <s:form>
representing a security token (Spring security) which is automatically initialized and maintained by the security framework (not Struts).
Hence, a getter and a setter for this field are not required in the corresponding action class.
Since there are no getter and setter for this field in the action class, it produces a message quite unnecessarily on the server terminal something like the following.
SEVERE: Developer Notification (set struts.devMode to false to disable this message): Unexpected Exception caught setting '_csrf' on 'class actions.CategoryAction: Error setting expression '_csrf' with value ['673b1d7a-6ab2-4241-86b9-0ccfe8094356', ]
This message itself can just be suppressed by disabling struts.devMode
either in web.xml
or struts.xml
(or even in struts.properties
).
But is there a way to bypass this field so that it does not even reach the action class? Simply because the value of this field is going to be used by the Spring security framework and not Struts. It is not needed by Struts at all.
One of the action classes (it is just a test case):
@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value = "struts-default")
public final class TestAction extends ActionSupport implements Preparable
{
public TestAction() {}
//Some validators as required.
@Action(value = "AddOrUpdate",
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", "validation.validateAnnotatedMethodOnly", "true"})
})
public String insertOrUpdate(){
// Do something. Add or update a row to the database (one at a time).
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", "validation.validateAnnotatedMethodOnly", "true"})})
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 Struts form which is bound to the action class above.
<s:form namespace="/admin_side" action="Test" validate="true" id="dataForm" name="dataForm">
<!--Some Struts elements as required like <s:textfield>-->
<s:hidden name="%{#attr._csrf.parameterName}" value="%{#attr._csrf.token}"/>
<!--This hidden field is automatically initialized to a random, hard-to-guess string-->
<!--Its name is _csrf which is mandatory by design, AFAIK.-->
<s:submit value="Submit" action="AddOrUpdate"/>
<!--The action of this button is mapped to insertOrUpdate() method in the action class.-->
<!--When this button is clicked, the insertOrUpdate() method in the action class is invoked.-->
<s:form>