I am making JQuery Ajax posts and would like any actionmessages
, actionerrors
, and fielderrors
added to in the action back in the response (in JSON format).
I added this result:
<result name="input" type="json">
<param name="ignoreHierarchy">false</param>
<param name="includeProperties">fieldErrors,actionErrors</param>
</result>
to my action configuration in the struts.xml
.
I am getting: {"actionErrors":[],"fieldErrors":{}}
back as a response, despite there being field errors on the value stack.
If I change my result configuration to:
<result name="input" type="json">
<param name="ignoreHierarchy">false</param>
<param name="root">fieldErrors</param>
</result>
the JSON response is I expected::
{"thePropertyWithValidationError":["You must supply correct information."]}
I would really like both action errors and field errors included in the response, if possible.
Any ideas? Thank you so much in advance!!
Edit:
I think I may need to utilize some sort of regular expression...I tried:
<result name="input" type="json">
<param name="ignoreHierarchy">false</param>
<param name="includeProperties">fieldErrors\[\d+\],actionErrors\[\d+\]</param>
</result>
with the same result:
{"actionErrors":[],"fieldErrors":{}}
I also found this bug report, which may be contributing to my issues as I am using Struts v2.2.1. (v2.2.2 is not yet out)
Edit #2:
Perhaps the JSONValidationInterceptor is what I need...I can't seem to figure out how to use it with my custom JQuery Ajax posts...
I am using the json interceptor to populate my properties-below is my action configuration:
<action name="MyAction" method="add" class="com.test.actions.MyAction">
<interceptor-ref name="json" />
<interceptor-ref name="jsonValidationWorkflowStack"/>
<interceptor-ref name="MyCustomInterceptor" />
<result name="success" type="json" />
</action>
I am posting:
{"struts.enableJSONValidation":"true", "testProperty":"true"}
The response is just forwarding to my global results mapping, error.jsp (with the field errors displayed as I have them set to display in the error.jsp):
<global-results>
<result name="error">/WEB-INF/jsp/error.jsp</result>
<result name="Exception">/WEB-INF/jsp/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Throwable" result="Exception" />
</global-exception-mappings>
I guess I was expecting that if there were fielderrors/actionerrors on the stack, they would be returned as JSON?
I figured out how to return ActionErrors, ActionMessages, and FieldErrors in the JSON result!
Below is a sample package- I set a up a global error handler that spits out the action errors, field errors, and action messages as JSON:
<!--myBase has interceptor stack defined-->
<package name="JsonResults" namespace="/json" extends="myBase">
<global-results>
<result name="input" type="json">
<param name="ignoreHierarchy">false</param>
<param name="includeProperties">actionErrors\[\d+\], fieldErrors\..+$, actionMessages\[\d+\]</param>
</result>
<result name="error" type="json">
<param name="ignoreHierarchy">false</param>
<param name="includeProperties">actionErrors\[\d+\], fieldErrors\..+$, actionMessages\[\d+\]</param>
</result>
<result name="Exception" type="json">
<param name="ignoreHierarchy">false</param>
<param name="includeProperties">actionErrors\[\d+\], fieldErrors\..+$, actionMessages\[\d+\]</param>
</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Throwable" result="Exception" />
</global-exception-mappings>
<!-- sample action -->
<action name="SampleAction" method="loadSamples" class="com.sample">
<result name="success" type="json">
<param name="ignoreHierarchy">false</param>
<param name="includeProperties">sampleComplexBean\[\d+\]\..+$, actionMessages\[\d+\]</param>
</result>
</action>
</package>
I can check in my JQuery Javascript if action errors or field errors exist:
/**
* Checks the passed in json and searches for the
* existence of an "actionErrors" or "fieldErrors" objects
*
* @param json The JSON to check for errors
* @returns {Boolean} true if errors exist; false otherwise
*/
function areActionOrFieldErrorInJson(json) {
var errorsExist = false;
if ( json != null && ( json.actionErrors != null || json.fieldErrors != null ) ) {
errorsExist = true;
}
return errorsExist;
}
or loop through them as follows:
if ( json.actionErrors != null && json.actionErrors.length !== 0 ) {
$.each(json.actionErrors, function(e) {
doStuff(this);
});
}