简体   繁体   中英

@ExceptionHandler not catching exceptions being thrown from Spring Formatters

I have a controller that serves as REST web service and one of my methods is expecting a model which in this model I have a member variable of type MyObjectId .

public class MyModel {

    private MyObjectId objectId;

    public MyObjectId getMyObjectId() {
        return objectId;
    }

    public void setMyObjectId(final MyObjectId objectId) {
        this.objectId = objectId;
    }
}

I have a custom implementation of a Formatter (org.springframework.format) for MyObjectId and this is my parse method:

@Override
public MyObjectId parse(final String text, final Locale locale) throws ParseException {
    // If the string is invalid it will throw an IllegalArgumentException
    return MyObjectIdConvertor.convert(text);
}

In my spring-servlet.xml I registered my formatter:

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="formatters">
        <set>
            <bean class="com.foo.MyObjectIdFormatter"/>
        </set>
    </property>    
</bean>

Now my problem is that when an exception is thrown from the Formatter it is not being caught by any of the @ExceptionHandler methods. Therefore the response is being output in this format:

org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'filterModel' on field 'myObjectId': rejected value [foo123123]; codes [typeMismatch.filterModel.myObjectId,typeMismatch.myObjectId,typeMismatch.com.foo.MyObjectId,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [filterModel.myObjectId,myObjectId]; arguments []; default message [myObjectId]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'com.MyObjectId' for property 'myObjectId'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type com.MyObjectId for value 'foo123123'; nested exception is java.lang.NumberFormatException: For input string: "foo123123"]

How can I make this type of exception begin caught by an @ExceptionHandler . This one of my exception handler methods:

@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseEntity<String> handleException(final Exception ex) {

    LOG.error("Error handling request", ex);
    return new ResponseEntity<>(StringUtils.hasText(ex.getMessage()) ? ex.getMessage() : "Error handling request", HttpStatus.BAD_REQUEST);
}

I had the same situation

I don't handle the Formatter exception in the @Controller

Checking the following:

codes [typeMismatch.filterModel.myObjectId,typeMismatch.myObjectId,typeMismatch.com.foo.MyObjectId,typeMismatch];

I suggest you work around ValidationMessages.properties (you need configure LocalValidatorFactoryBean and ReloadableResourceBundleMessageSource )

For example I have

typeMismatch.person.dateBirth=Invalid data, format for Date of Birth is incorrect!

Then assuming if the wise and friendly user writes an invalid date according the formatter, my DateFormatter class, like in your case throws an exception, but since I have defined the code typeMismatch.person.dateBirth the error message is show in my web form.

Observe our codes are similar in some way. I think Spring looks somewhere if some of the codes exists to show an appropriate message, since you have none code the exception stack trace remains, in my case how I have the code and the customized message, it is presented in my web form.

I didn't test yet how that customized error message should fit well through REST . But in my case if some Formatter throws an error I am sure that the code exists in the ValidationMessages.properties file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM