JBoss.orgCommunity Documentation

Chapter 46. Validation

46.1. Providing a ValidatorAdapter to RESTEasy
46.2. Telling RESTEasy what needs validation
46.3. Bean Validation API integration

RESTEasy is able to trigger validation in beans and method invocation. It introduces a new interface - org.jboss.resteasy.spi.validation.ValidatorAdapter - which is intended to decouple RESTEasy from the real validation API. Although the focus is integrate with the Bean Validation (JSR-303), this interface (hopefully ;)) allows us to integrate with any validation framework.

RESTEasy will try to obtain an implementation of ValidatorAdapter through a ContextResolver provider in the classpath. We can provide RESTEasy with an implementation like follow:
@Provider
public class MyValidatorContextResolver implements ContextResolver<ValidatorAdapter> {
   
   @Override
   public ValidatorAdapter getContext(Class<?> type) {
      return new MyValidator(); 
   }
   
}
There are two new annotations - org.jboss.resteasy.spi.validation.ValidateRequest and org.jboss.resteasy.spi.validation.DoNotValidateRequest - that are used to indicate what needs validation or not. We can tell RESTEasy to validate any method in a resource annotating the resource:
@Path("resourcePath")
@ValidateRequest
public interface Resource {
   
   @POST
   @Path("insert")
   public String insert(...

   @GET
   @Path("list")
   public String list(...
    
}
We can tell it to validate just some methods in an interface:
@Path("resourcePath")
public interface Resource {
   
   @POST
   @Path("insert")
   @ValidateRequest
   public String insert(...

   @GET
   @Path("list")
   public String list(...
    
}
This way RESTEasy will only trigger validation in insert method. It's possible to say what methods you don't want to be validated:
@Path("resourcePath")
@ValidateRequest
public interface Resource {
   
   @POST
   @Path("insert")
   public String insert(...
   
   @GET
   @Path("list")
   @DoNotValidateRequest
   public String list(...
    
}

Important

By default RESTEasy will not validate any method. To enable validation it's required to annotate the resource or method with ValidateRequest.

The Bean Validation API (JSR-303) defines a meta-data model and API for bean validation based on annotations, with overrides and extended meta-data through the use of XML validation descriptors. There are some implementations of the API, and initially we integrate just with Hibernate Validator, which is the reference implementation to the JSR-303.

The integration between the API implementation and RESTEasy is done through the resteasy-hibernatevalidator-provider component. In order to integrate, we need to add resteasy-hibernatevalidator-provider and hibernate-validator to the classpath. With maven it's just a matter of including the following dependency:

<dependency>
   <groupId>org.jboss.resteasy</groupId>
   <artifactId>resteasy-hibernatevalidator-provider</artifactId>
   <version>2.3.6.Final</version>
</dependency>

With this in the classpath, we can use all the infrastructure of the Bean Validation API and Hibernate Validator implementation:

@Path("resourcePath")
@ValidateRequest
public interface Resource {
   
   @POST
   @Path("insert")
   public String insert(
      @FormParam("name") 
      @NotNull 
      @Size(min=1,max=255) 
      String name,
      
      @FormParam("version")
      @Pattern("\\d")
      String version
   );
   
   @GET
   @Path("list")
   public String list(
      @QueryParam("keyword") 
      @NotNull 
      String 
      keyword
   );
    
}

If a @Form parameter needs to be used, or the parameter represents the body of the request, this parameter needs to be annotated with @Valid from Bean Validation API:

@Path("resourcePath")
@ValidateRequest
public interface Resource {
   
   @POST
   @Path("insert")
   public String insert(
      @Form 
      @Valid
      FormBean form
   );
   
}

The ValidatorAdapter API doesn't define an exception model yet. Each adapter implementation throws its particular implementation exception.

@Path("resourcePath")
@ValidateRequest
public interface Resource {
   
   @POST
   @Path("insert")
   public String insert(
      @Form 
      @Valid
      FormBean form
   );
   
}