Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
h2. Bean Validation Component

*Available as of Camel 2.3*

The Validation component performs bean validation of the message body using the Java Bean Validation API ([JSR 303|http://jcp.org/en/jsr/detail?id=303]). Camel uses the reference implementation, which is [Hibernate Validator|http://docs.jboss.org/hibernate/stable/validator/reference/en/html_single/].

Maven users will need to add the following dependency to their {{pom.xml}} for this component:
{code:xml}
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-bean-validator</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>
{code}


h3. URI format

{code}
bean-validator:something[?options]
{code}

or

{code}
bean-validator://something[?options]
{code}

Where *something* must be present to provide a valid url
You can append query options to the URI in the following format, ?option=value&option=value&...

h3. URI Options
{div:class=confluenceTableSmall}
|| Option || Default || Description ||
| {{group}} | {{javax.validation.groups.Default}} | The custom validation group to use. |
| {{messageInterpolator}} | {{org.hibernate.validator.engine.\\ResourceBundleMessageInterpolator}} | Reference to a custom {{javax.validation.MessageInterpolator}} in the [Registry]. |
| {{traversableResolver}} | {{org.hibernate.validator.engine.resolver.\\DefaultTraversableResolver}} | Reference to a custom {{javax.validation.TraversableResolver}} in the [Registry]. |
| {{constraintValidatorFactory}} | {{org.hibernate.validator.engine.\\ConstraintValidatorFactoryImpl}} | Reference to a custom {{javax.validation.ConstraintValidatorFactory}} in the [Registry]. |
{div}

h3. ServiceMix4/OSGi Deployment.

The bean-validator when deployed in an OSGi environment requires a little help to accommodate the resource loading specified in JSR303, this was fixed in Servicemix-Specs 1.6-SNAPSHOT.

h3. Example

Assumed we have a java bean with the following annotations

{code:title=Car.java}
public class Car {

    @NotNull
    private String manufacturer;

    @NotNull
    @Size(min = 5, max = 14, groups = OptionalChecks.class)
    private String licensePlate;
    
    // getter and setter
}
{code}

and an interface definition for our custom validation group

{code:title=OptionalChecks.java}
public interface OptionalChecks {
}
{code}

with the following Camel route, only the *@NotNull* constraints on the attributes manufacturer and licensePlate will be validated (Camel uses the default group {{javax.validation.groups.Default}}).

{code}
from("direct:start")
.to("bean-validator://x")
.to("mock:end")
{code}

If you want to check the constraints from the group {{OptionalChecks}}, you have to define the route like this

{code}
from("direct:start")
.to("bean-validator://x?group=OptionalChecks")
.to("mock:end")
{code}

If you want to check the constraints from both groups, you have to define a new interface first

{code:title=AllChecks.java}
@GroupSequence({Default.class, OptionalChecks.class})
public interface AllChecks {
}
{code}

and then your route definition should looks like this

{code}
from("direct:start")
.to("bean-validator://x?group=AllChecks")
.to("mock:end")
{code}

And if you have to provide your own message interpolator, traversable resolver and constraint validator factory, you have to write a route like this

{code}
<bean id="myMessageInterpolator" class="my.ConstraintValidatorFactory" />
<bean id="myTraversableResolver" class="my.TraversableResolver" />
<bean id="myConstraintValidatorFactory" class="my.ConstraintValidatorFactory" />

from("direct:start")
.to("bean-validator://x?group=AllChecks&messageInterpolator=#myMessageInterpolator&traversableResolver=#myTraversableResolver&constraintValidatorFactory=#myConstraintValidatorFactory")
.to("mock:end")
{code}

It's also possible to describe your constraints as XML and not as Java annotations. In this case, you have to provide the file {{META-INF/validation.xml}} which could looks like this

{code:title=validation.xml}
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
	xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration">
	<default-provider>org.hibernate.validator.HibernateValidator</default-provider>
	<message-interpolator>org.hibernate.validator.engine.ResourceBundleMessageInterpolator</message-interpolator>
	<traversable-resolver>org.hibernate.validator.engine.resolver.DefaultTraversableResolver</traversable-resolver>
	<constraint-validator-factory>org.hibernate.validator.engine.ConstraintValidatorFactoryImpl</constraint-validator-factory>
	
	<constraint-mapping>/constraints-car.xml</constraint-mapping>
</validation-config>
{code}

and the {{constraints-car.xml}} file

{code:title=constraints-car.xml}
<?xml version="1.0" encoding="UTF-8"?>
<constraint-mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"
	xmlns="http://jboss.org/xml/ns/javax/validation/mapping">
	<default-package>org.apache.camel.component.bean.validator</default-package>
	
	<bean class="CarWithoutAnnotations" ignore-annotations="true">
		<field name="manufacturer">
			<constraint annotation="javax.validation.constraints.NotNull" />
		</field>
		
		<field name="licensePlate">
			<constraint annotation="javax.validation.constraints.NotNull" />
			
			<constraint annotation="javax.validation.constraints.Size">
				<groups>
					<value>org.apache.camel.component.bean.validator.OptionalChecks</value>
				</groups>
				<element name="min">5</element>
				<element name="max">14</element>
			</constraint>
		</field>
	</bean>
</constraint-mappings>
{code}


{include:Endpoint See Also}