JSR-303 and conditional validation with self-validation POJOs

The JSR-303 validation is great. Yes, really. But sometimes it is just too great. Imagine yourself having to do some complex validation on a single data-transfer POJO. Maybe you are collecting the data from a web-form and you need to show an error somewhere, but the default validation rules just don't fit, your to-be-enforced constraints are just too complex to be enforced using default constraints. It can be as simple as having to check for a string to be submitted, if, and only if, a checkbox is selected, but yet it is too complex to achieve using the default rules.

Yes, you can define a custom annotation, write a validator, a unit-test for validator, then define a message for the validation error in your Validation.properties file and so on.

Do you really have to do all that? If you are going to reuse the code – yes. But if it is really just a one-time shot? Then a simple short-cut can do the trick: just define a method in your POJO class that will do the validation, then annotate it with an @AssertTrue. 

public class YourDataTransferObject {

// … your fields, getters and setters

@AssertTrue(message="Your custom validation message")
public boolean isValid() {
  //...do your non-standard validation stuff here

  //and return true if the object is valid
  }

}

And, assuming you have a Spring form with an instance of YourDataObject as your command object (form object), your JSP can contain the following code.

YourSpringWebForm.jsp:

<form:errors path="valid">

<!-- Put it wherever you like: next to an input field, in the header, etc. -->

No boilerplate code. It's that simple. You might need to write a unit test for your method (you probably do), but it's still a lot simpler than setting up a whole bunch of mock objects to test a custom validator object.

This approach can save you some effort, if you don't really plan to reuse the code. If you ever need to reuse the validation logic – the refactoring is very simple: you just move the validation code from your POJO to a validator object. 


P.S. Disclaimer: this is just a quick-and-dirty solution for one-time validation scenarios. I don't suggest using this approach in all and every case, but in my experience, it can save some time now and then.

Comments

Popular posts from this blog

Multi-threading skills - what do you mean by that?

Code reviews, recommended reading

Spring Framework and Code Obscurity