Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grails JSON marshaller for FieldErrors

I'm trying to create a custom marshaller for org.springframework.validation.FieldError so I can avoid putting extraneous and possibly sensitive data in my JSON response, which includes MyCommandObject.errors.

However my FieldError marshaller isn't working at all, this is what I have in my BootStrap.groovy under the init method.

    def fieldErrorMarshaller = {
        log.info("field error marshaller $it")
        def returnArray = [:]

        returnArray['field'] = it.field
        returnArray['message'] = it.message

        return returnArray
    }

    JSON.registerObjectMarshaller(FieldError, fieldErrorMarshaller)

I am not seeing any explicit errors or the marshaller logging. Any idea what might be going wrong here?

like image 467
James McMahon Avatar asked Oct 11 '25 22:10

James McMahon


1 Answers

Grails register a instance of ValidationErrorsMarshaller that handle all errors, so your FieldError marshaller will never get called.

//convertAnother is not called for each error. That's the reason of your custom marshalled not been called.
for (Object o : errors.getAllErrors()) {
    if (o instanceof FieldError) {
        FieldError fe = (FieldError) o;
        writer.object();
        json.property("object", fe.getObjectName());
        json.property("field", fe.getField());
        json.property("rejected-value", fe.getRejectedValue());
        Locale locale = LocaleContextHolder.getLocale();
        if (applicationContext != null) {
            json.property("message", applicationContext.getMessage(fe, locale));
        }
        else {
        ...

Looking at ConvertersGrailsPlugin (descriptor of the plugin) this is registered as a Spring Bean, so you can create another bean and register with the same name, overriding the marshalObject() to fit your needs (not tested, may need more code).

class MyErrorsMarshaller implements ObjectMarshaller<JSON>, ApplicationContextAware {
    ApplicationContext applicationContext;

    public boolean supports(Object object) {
        return object instanceof Errors;
    }

    public void marshalObject(Object object, JSON json) throws ConverterException {
    ...
    }

}

resources.groovy

jsonErrorsMarshaller(MyErrorsMarshaller)

errorsJsonMarshallerRegisterer(ObjectMarshallerRegisterer) {
    marshaller = { MyErrorsMarshaller om -> }
    converterClass = grails.converters.JSON
}

Reference for ValidationErrorsMarshaller.

Reference for ConvertersGrailsPlugin.