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 follows the Bean Validation specification and the incoming HTTP requests can be validated with 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)
{
...
}
Now, the HTTP request's entity body (the
incomingTask
parameter) will be validated prior to invoking the method.
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, a
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 Solder exception 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 the 400 (Bad request) status code. Furthermore,
it sends messages relevant to the
violated constraints within the
message body of the HTTP response.
Example 58.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 58.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 an
@ValidateRequest
annotation, the fields
of a resource are validated by default.
Since the JAX-RS injection occurs only at resource creation time,
do
not use the
JAX-RS field injection for
other than
@RequestScoped
resources.
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 58.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 validates only JavaBean parameters (as opposed to primitive types, Strings and so on). Therefore, to validate these types of parameters, either use resource field validation described in Section 58.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. To trigger the validation, annotate the parameter with a
javax.validation.Valid
annotation.
Example 58.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(@Valid @Form MyForm form) {...}
Table 58.1.
@ValidateRequest
annotation properties
@ValidateRequest
attribute
| Description | Default value |
---|---|---|
validateMessageBody
| Enabling/disabling validation of message body parameters | true |
validateResourceFields
| Enabling/disabling validation of 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 for validation of web service parameters. These constraints are usually weaker than the default constraints of a domain model. Take partial updates as an example.
Consider the following example:
Example 58.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 values of modified fields
are required to be
sent within the update request, while
the non-null
values of the
received object are updated. Therefore, two groups of
constraints are
needed: group for
partial updates
(including
@Size
and
@Email
, excluding @NotNull
) and the
default group
(@NotNull).
A validation group is a simple Java interface:
Example 58.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 58.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. |