Spring MVC : Preventing Exceptions when binding model attribute

2.4k views Asked by At

In my model(s) I use Numeric data types like Long, Integer etc. When I do form post of them, but supply String, it outputs Exception stack trace, including like NumberFormatException. How can i properly wrap this so that UI does not see the exception stack trace ?

2

There are 2 answers

3
Ralph On BEST ANSWER

You need to have a BindingResult argument right after the command argument (with @Value annotation) in your controller. Then you can inspect the bindingResult and decide what to do with the stuff that could`t be bind.

When you have that BindingResult argument then the controller method gets invoked, even with an binding error, and you have to handle the error yourself.

Typically it would look a bit like this example (create a user or render the user create page again):

@RequestMapping(method = RequestMethod.POST)
public ModelAndView create(@Valid UserCreateCommand userCreateCommand,
                           BindingResult bindingResult) {
   if (bindingResult.hasErrors()) {
        //or some of your handling for bindingResult errors
        return new ModelAndView("user/create", userCreateCommand", userCreateCommand);
    } else {
    ...
    }
}

But how do I differentiate the normal validation errors vs. validation errors occuring due to NumberFormatException ?

The BindingResult has several methods to obtain the FieldErrors, for example BindingResult.getFieldErrors(). and a FieldError has the property boolean isBindingFailure()

0
jgr On

If you want to display customized message for that exception you should configure Spring to use message.properties file and specify 'typeMismatch.className.propertyName' message or global message for typeMismatch.

For example (Spring 3.2): In servlet-config.xml

<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
p:basename="classpath:messages/messages">
</bean>

In src/main/resources/messages/messages.properties

typeMismatch = Invalid data format!

In controller:

public String addObject(@Valid @ModelAttribute("objectForm")
ObjectForm objectForm, BindingResult result, Model model)
{
        if (result.hasErrors())
        {
            return "/addObject";
        }
    //...
}

In jsp:

<form:errors path="propertyName" cssClass="divErrorsServer" element="div" />

You can also use:

System.out.println(result.getAllErrors());

To see what codes you can add in messages file for that error. For example when I used String on private Double weight field I got those codes:

[typeMismatch.objectForm.weight,
typeMismatch.weight,
typeMismatch.java.lang.Double,
typeMismatch]