Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>With Spring MVC, there are 3 different ways to perform validation : using annotation, manually, or a mix of both. There is not a unique "cleanest and best way" to validate, but there is probably one that fits your project/problem/context better.</p> <p>Let's have a User :</p> <pre><code>public class User { private String name; ... } </code></pre> <p><strong>Method 1 :</strong> If you have Spring 3.x+ and simple validation to do, use <code>javax.validation.constraints</code> annotations (also known as JSR-303 annotations).</p> <pre><code>public class User { @NotNull private String name; ... } </code></pre> <p>You will need a JSR-303 provider in your libraries, like <a href="http://www.hibernate.org/subprojects/validator.html" rel="noreferrer">Hibernate Validator</a> who is the reference implementation (this library has nothing to do with databases and relational mapping, it just does validation :-).</p> <p>Then in your controller you would have something like :</p> <pre><code>@RequestMapping(value="/user", method=RequestMethod.POST) public createUser(Model model, @Valid @ModelAttribute("user") User user, BindingResult result){ if (result.hasErrors()){ // do something } else { // do something else } } </code></pre> <p>Notice the @Valid : if the user happens to have a null name, result.hasErrors() will be true.</p> <p><strong>Method 2 :</strong> If you have complex validation (like big business validation logic, conditional validation across multiple fields, etc.), or for some reason you cannot use method 1, use manual validation. It is a good practice to separate the controller’s code from the validation logic. Don't create your validation class(es) from scratch, Spring provides a handy <code>org.springframework.validation.Validator</code> interface (since Spring 2).</p> <p>So let's say you have</p> <pre><code>public class User { private String name; private Integer birthYear; private User responsibleUser; ... } </code></pre> <p>and you want to do some "complex" validation like : if the user's age is under 18, responsibleUser must not be null and responsibleUser's age must be over 21.</p> <p>You will do something like this</p> <pre><code>public class UserValidator implements Validator { @Override public boolean supports(Class clazz) { return User.class.equals(clazz); } @Override public void validate(Object target, Errors errors) { User user = (User) target; if(user.getName() == null) { errors.rejectValue("name", "your_error_code"); } // do "complex" validation here } } </code></pre> <p>Then in your controller you would have :</p> <pre><code>@RequestMapping(value="/user", method=RequestMethod.POST) public createUser(Model model, @ModelAttribute("user") User user, BindingResult result){ UserValidator userValidator = new UserValidator(); userValidator.validate(user, result); if (result.hasErrors()){ // do something } else { // do something else } } </code></pre> <p>If there are validation errors, result.hasErrors() will be true.</p> <p>Note : You can also set the validator in a @InitBinder method of the controller, with "binder.setValidator(...)" (in which case a mix use of method 1 and 2 would not be possible, because you replace the default validator). Or you could instantiate it in the default constructor of the controller. Or have a @Component/@Service UserValidator that you inject (@Autowired) in your controller : very useful, because most validators are singletons + unit test mocking becomes easier + your validator could call other Spring components.</p> <p><strong>Method 3 :</strong> Why not using a combination of both methods? Validate the simple stuff, like the "name" attribute, with annotations (it is quick to do, concise and more readable). Keep the heavy validations for validators (when it would take hours to code custom complex validation annotations, or just when it is not possible to use annotations). I did this on a former project, it worked like a charm, quick &amp; easy.</p> <p><strong>Warning :</strong> you must not mistake <strong>validation handling</strong> for <strong>exception handling</strong>. <a href="https://stackoverflow.com/a/12661291/400545">Read this post</a> to know when to use them.</p> <p>References :</p> <ul> <li><a href="http://web.archive.org/web/20120508030459/http://blog.orange11.nl/2009/08/04/bean-validation-integrating-jsr-303-with-spring" rel="noreferrer">A very interesting blog post about bean validation</a> (<a href="http://blog.orange11.nl/2009/08/04/bean-validation-integrating-jsr-303-with-spring/" rel="noreferrer">Original link</a> is dead)</li> <li><a href="http://alasdoo.com/2011/07/data-validation-conversion-basics-custom-error-messages-in-spring-mvc" rel="noreferrer">Another good blog post about validation</a></li> <li><a href="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html" rel="noreferrer">Latest Spring documentation about validation</a></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload