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

Spring Framework and Code Obscurity

High-volume sampling: algorithms’ comparison

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