3

I seek the best way to handle error validation in the @service layer in a spring mvc application.

I have a @Controller and a @Service class.

My controller :

public String saveProduct(Product product) {
    myService.saveProduct(product);
    return "view";
}

My service :

public void saveProduct(Product product) {
    // some validation here
    myDao.save(product);
}

Now let's say that the validation leads to 2 or 3 errors (the color is not appropriate, the supplier can't deliver the product right now, and so on...) and I have to display all of them at the same time.

How do I transmit those errors to my controller, and then to my jsp ? Using an "Errors" object ? An exception containing all those errors ?

I've already looked here : Passing errors back to the view from the service layer but I can't find a convenient answer. Do I really have to create unchecked exceptions for EACH error ? And what if I have a 20 or 30 errors ?

Community
  • 1
  • 1
Christos Loupassakis
  • 1,216
  • 3
  • 16
  • 23
  • 1
    I'd go with Exceptions - thats what they're for. Just use some generic exception class and pass in the message, to be displayed in the JSP. The message needs to be coded regardless of which method you use. – nickdos Sep 18 '12 at 06:26
  • What if I have 3 error messages to display at same time ? Do I have to throw an exception containing 3 messages ? – Christos Loupassakis Sep 18 '12 at 22:06
  • Any reason you're not using JSR 303 or Spring Bean validation? E.g. http://stackoverflow.com/questions/6835122/using-both-jsr-303-and-traditional-bean-validation – nickdos Sep 18 '12 at 23:19
  • I'm already using both, in my controller (for form validation, like name length, email format...). But in the service I have to make additional controls, like supplier availability, and other stuff). The link I gave in the problem description reflects my current situation... but my main concern is how to display multiple messages at the same time. – Christos Loupassakis Sep 19 '12 at 11:14

1 Answers1

4

Finally I created a custom exception to handle the functional errors :

public class ServiceException extends Exception {  
    private List<String> errors = new ArrayList<>();
    (...)
}

I also created a ValidationErrorsHelper class with the following method :

public static void rejectErrors(final BindingResult result, final List<String> errors) {
    if (errors != null) {
        for (final String error : errors) {
            result.reject(error);
        }
    }
}

And in my controller class, I catch the exception :

try {
    this.myService.myFunction(...);
} catch (final ServiceException e) {
    ValidationErrorsHelper.rejectErrors(result, e.getErrors());
}

This is the best way I could find. If there's any better suggestion I'm all ears !

Christos Loupassakis
  • 1,216
  • 3
  • 16
  • 23
  • I have done pretty much the same adding a member in my custom exceptions that will hold an error label. The controller adds the error label in the model. The label is then resolved in the jsps. Your solution sounds much better if you want to return more than one error at once. – ampofila Mar 17 '14 at 14:20
  • I would like to know how are you filling errors in your exception object? – prateekmathur1991 Nov 10 '16 at 11:02
  • Well it's pretty standard, in the ServiceException class you should have methods like "public void addError(String error)". It all depends on your needs. – Christos Loupassakis Nov 16 '16 at 09:33
  • Don't forget to override `fillInStackTrace` so that you don't... fill in the stack trace... http://stackoverflow.com/questions/11434431/exception-without-stack-trace-in-java – Charles Wood Jan 09 '17 at 15:59