Opentaps 2 Service Validation

From Opentaps Wiki
Revision as of 14:50, 30 January 2012 by Jwickers (talk | contribs) (Protected "Opentaps 2 Service Validation": Sysop page [edit=sysop:move=sysop])
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

There are currently two level of validations, one at the service level which validates the parameters given, and one at the persistence level.

General Concept

Validation at those levels is implemented using Bean Validation (JSR-303), which simply consist of annotations on a POJO's properties or accessors. There are numerous online articles to learn more about it, eg:

Some validators are quite simple, like javax.validation.constraints.NotNull, and it is also very easy to define your own, like for example org.opentaps.validation.contraints.NotEmpty.

A Validator can also be set on a class itself when complex validation involving multiple properties is needed.

Validation on Entities

JPA supports Bean Validation internally so an entity which is annotated will only be persisted if it is valid.

Validation in the Services

Validation in the Services is done in a similar manner, the Input and Output objects are annotated and the service implementation is responsible for calling the validator.

For this the validation.api bundle defines a ValidationService which is provided by the validation.impl bundle which itself simply expose the implementation given by Geronimo.

A typical pattern in the service implementation can be seen in and is basically:

 Set<ConstraintViolation<MyServiceInput>> inputViolations = validationService.getValidator().validate(input);
 if (inputViolations.size() > 0) {
   throw new ServiceValidationException("My service failed.", (Set) inputViolations);
 try {
   // do something involving  persistence
 } catch (ConstraintViolationException e) {
   throw new ServiceValidationException("My service failed.", e);
 } catch (PersistenceException e) {
   throw new ServiceException("My service failed.", e);
 // populate the output
 MyServiceOutput out = new MyServiceOutput();
 Set<ConstraintViolation<MyServiceOutput>> outputViolations = validationService.getValidator().validate(out);
 if (outputViolations.size() > 0) {
   throw new ServiceValidationException("My service failed.", (Set) outputViolations);

Sending Validation Errors to the Client

As an example the Note rest service `` simply extends `` which implements an exception handler that translates a `ServiceValidationException` into a JSON structure.

Part of the JSON response includes a `errorDetail` object which is an array of `ServiceValidationException.FieldError` which contains 3 fields:

  • field which is the field name in the service interface that was not valid
  • message which is the error message returned by the validator
  • value which was the value given that failed validation

The client can then read that response to present the errors to the user.