Announcement Announcement Module
No announcement yet.
Spring Validation inside service layer and MVC error binding, how? Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring Validation inside service layer and MVC error binding, how?


    I'm facing an issue that sounds so ordinary that I must be approaching it poorly. This is the case:

    We use Spring Validation to validate MVC inputs, and BindingResult is used to report the errors on the first layer (example):

    @RequestMapping(value="/url.jsp", method=RequestMethod.POST)
    public String something(@ModelAttribute MyObject obj, BindingResult result, Model model) {
    	validator.validate(obj, result);
    	if (!result.hasErrors()) {
    	model.addAttribute("obj", obj);
    	return "page";
    Now we need to offer webservices for some methods, and so we'd like to unify the validation code (which for now is mostly on the controllers - not advisable, I know), moving it to the services layer. And here is the issue: how to validate inside the services layer, and retain error binding, so that we still have friendly errors messages on our JSPs.

    The BindingResult object would be needed inside the services layer to validate and properly display the errors on the JSP. I don't want to add this variable as another parameter to services methods, as it looks like I'm tying the services layer to the MVC implementation. The two approaches I envisioned (about to be tested):
    1. Services layer create an 'Errors' object to bind on; if any errors found, throw a specific exception containing the Errors object, catching it on the controller and passing the errors from the Errors to the BindingResult object; looks bad, uses exception as control flow and I don't know if it would work at all;
    2. Controller puts the BindingResult object on a ThreadLocal variable, which will be accessed from the services to validate on, and errors would raise exceptions as usual; looks a bit better, but more complicated than it should, plus it would require the controllers to call service methods on try-finally blocks to remove the BindingResult from the ThreadLocal, avoiding memory leaks and validation on BindingResult objects from previous method calls.

    As a simple approach, I could validate twice, binding errors when on the controller, turning them into exceptions when on the service layer. For sure it works, but will double-validate every valid input. I'd prefer a single point of validation, if possible (plus all MVC-specific validation only on the controllers, of course).

    So, how can I handle this in a clean way? Any suggestion is welcome. Even if I should use something else for this instead of Spring Validator, because I'm sure I'm not the first with this issue, and it's too much hassle and dirty code for an ordinary situation.

    Note: Spring Framework + Spring MVC 3.1.0 and Spring Webservices 2.1.0

    Last edited by mdrg; Sep 10th, 2012, 09:33 AM.