I\'m trying to group the code that logs the exceptions and render a nice view in a few methods. At the moment the logic is sometime in the @RequestHand
I've wondered this too.
In order to handle bean validation in a way that allows for a non-global error view to display any ConstraintViolationException
s that may be thrown, I opted for a solution along the lines of what @Stefan Haberl proposed:
Explicitly catch the exception to tell Spring MVC that you know what you're doing (you could use the Template pattern to refactor exception handling logic into one single place)
I created a simple Action
interface:
public interface Action {
String run();
}
And an ActionRunner
class which does the work of ensuring ConstraintViolationException
s are handled nicely (basically the messages from each ConstraintViolationException
is simply added to a Set
and added to the model):
public class ActionRunner {
public String handleExceptions(Model model, String input, Action action) {
try {
return action.run();
}
catch (RuntimeException rEx) {
Set errors = BeanValidationUtils.getErrorMessagesIfPresent(rEx);
if (!errors.isEmpty()) {
model.addAttribute("errors", errors);
return input;
}
throw rEx;
}
}
}
Java 8 makes this pretty nice to run within the controller action method:
@RequestMapping(value = "/event/save", method = RequestMethod.POST)
public String saveEvent(Event event, Model model, RedirectAttributes redirectAttributes) {
return new ActionRunner().handleExceptions(model, "event/form", () -> {
eventRepository.save(event);
redirectAttributes.addFlashAttribute("messages", "Event saved.");
return "redirect:/events";
});
}
This is to wrap up those action methods for which I'd like to explicitly handle exceptions that could be thrown due to Bean Validation. I still have a global @ExceptionHandler
but this deals with only "oh crap" exceptions.