SeamFramework.orgCommunity Documentation
Bean Validation (JSR-303) is a specification introduced as a part of Java EE 6. It aims to provide a standardized way of validating the domain model across all application layers.
The Seam REST module integrates with the Bean Validation specification. This allows incomming HTTP requests to be validated using this standardized mechanism.
Firstly, enable the
ValidationInterceptor
in the
beans.xml
configuration
file.
<interceptors>
<class>org.jboss.seam.rest.validation.ValidationInterceptor</class>
</interceptors>
Then, enable validation of a particular method by decorating
it with
the
@ValidateRequest
annotation.
@PUT
@ValidateRequest
public void updateTask(Task incommingTask)
{
...
}
By default, the entity parameter (the parameter with no annotations
that represent the body of the HTTP request) is
validated. If the
object is valid, the web service method is
executed.
Otherwise, the
ValidationException
exception
is thrown.
The
ValidationException
exception
is a simple carrier of constraint violations found by the
Bean
Validation provider. The exception can be handled by an
ExceptionMapper
or Seam Catch handler.
.
Seam REST comes with a built-in
ValidationException
handler
which is registered by default. The exception handler converts the
ValidationException
to an HTTP response with 400 (Bad request) status code. Furthermore,
messages relevant to the violated constraints are sent within the
message body of the HTTP response.
Example 3.1. HTTP response
HTTP/1.1 400 Bad Request
Content-Type: application/xml
Content-Length: 129
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<error>
<messages>
<message>Name length must be between 1 and 100.</message>
</messages>
</error>
Besides the message body, the JAX-RS specification allows various parts of the HTTP request to be injected into the JAX-RS resource or passed as method parameters. These parameters are usually HTTP form parameters, query parameters, path parameters, headers, etc.
Example 3.2. JAX-RS resource
public class PersonResource
{
@QueryParam("search")
@Size(min = 1, max = 30)
private String query;
@QueryParam("start")
@DefaultValue("0")
@Min(0)
private int start;
@QueryParam("limit")
@DefaultValue("20")
@Min(0) @Max(50)
private int limit;
...
If a method of a resource is annotated with
@ValidateRequest
annotation, the fields
of a resource are validated by default.
Since the JAX-RS injection occurs at resource creation time only,
do
not use the
JAX-RS field injection for other than
@RequestScoped
resources.
As a consequence of CDI-6, some containers are not able to perform JAX-RS field injection on an intercepted CDI bean. In this situation, JAX-RS setter injection can be used as a workaround.
The JAX-RS specification allows path parameters, query parameters, matrix parameters, cookie parameters and headers to be passed as parameters of a resource method.
Example 3.3. JAX-RS method parameters
@GET
public List<Person>search(@QueryParam("search") String query,
@QueryParam("start") @DefaultValue("0") int start,
@QueryParam("limit") @DefaultValue("20") int limit)
Currently, Seam REST does not validate primitive method parameters (including String ones). Therefore, either use resource field validation described in Section 3.1.2, “Validating resource fields” or read further and use parameter objects.
In order to prevent an oversized method signature when the number of parameters is too large, JAX-RS implementations provide implementations of the Parameter Object pattern . These objects aggregate multiple parameters into a single object. For example RESTEasy Form Object or Apache CXF Parameter Bean . These parameters can be validated by Seam REST.
Example 3.4. RESTEasy parameter object
public class MyForm {
@FormParam("stuff")
@Size(min = 1, max = 30)
private int stuff;
@HeaderParam("myHeader")
private String header;
@PathParam("foo")
public void setFoo(String foo) {...}
}
@POST
@Path("/myservice")
@ValidateRequest
public void post(@Form MyForm form) {...}
Table 3.1. @ValidateRequest annotation properties
@ValidateRequest attribute | Description | Default value |
---|---|---|
validateMessageBody | Enables/Disables validation of message body parameters. | true |
validateParameterObjects | Enables/Disables validation of parameter objects. | true |
validateResourceFields | Enables/Disables validation of fields fields of a JAX-RS resource. | true |
groups | Validation groups to be used for validation. | javax.validation.groups.Default |
In some cases, it is desired to have a specific group of constraints used to validate the web service parameters. These constraints are usually weaker compared to the default constraints of a domain model. Take partial updates as an example.
Consider the following example:
Example 3.5. Employee.java
public class Employee {
@NotNull
@Size(min = 2, max = 30)
private String name;
@NotNull
private String email;
@NotNull
private Department department;
// getters and setters
}
The Employee resource in the example above is not allowed to have the null value specified in any of its fields. Thus, the entire representation of a resource (including the department and related object graph) must be sent to update the resource.
When using partial updates, only the values of modified fields are required to be sent within the update request. Only the non-null values of the received object are updated. Therefore, two groups of constraints are needed: one for partial updates (including @Size and @Email, excluding @NotNull) and the default one (@NotNull).
A validation group is a simple Java interface:
Example 3.7. Employee.java
@GroupSequence({ Default.class, PartialUpdateGroup.class })
public class Employee {@NotNull
@Size(min = 2, max = 30, groups = PartialUpdateGroup.class)
private String name;
@NotNull
@Email(groups = PartialUpdateGroup.class)
private String email;
@NotNull
private Department department;
// getters and setters
}
The
| |
The
| |
The
|
Finally, the
ValidationInterceptor
is configured to validate the
PartialUpdateGroup
group
only.
Example 3.8. EmployeeResource.java
@Path("/{id}")
@PUT
@Consumes("application/xml")@ValidateRequest(groups = PartialUpdateGroup.class)
public void updateEmployee(Employee e, @PathParam("id") long id)
{
Employee employee = em.find(Employee.class, id);if (e.getName() != null)
{
employee.setName(e.getName());
}
if (e.getEmail() != null)
{
employee.setEmail(e.getEmail());
}
}
The partial update validation group is used for web service parameter validation. | |
Partial update — only the not-null fields of the transferred representation are used for update. The null fields are not updated. |