Spring 3 Validation - Java-Springs

Spring 3 introduces several enhancements to its validation support. First, the JSR-303 Bean Validation API is now fully supported. Second, when used progra matically, Spring's DataBinder can now validate objects as well as bind to them. Third, Spring MVC now has support for declaratively validating @Controller inputs.

Overview of the JSR-303 Bean Validation API

JSR-303 standardizes validation constraint declaration and metadata for the Java platform.Using this API, you annotate domain model properties with declarative validation constraints and the runtime enforces them. There are a number of built-in constraints you can take advantage of. You may also define your own custom constraints.

To illustrate, consider a simple PersonForm model with two properties:
public class PersonForm {
private String name;
private int age;
}

JSR-303 allows you to define declarative validation constraints against such properties:

public class PersonForm {
@NotNull
@Size(max=64)
private String name;
@Min(0)
private int age;
}

When an instance of this class is validated by a JSR-303 Validator, these constraints will be enforced.To learn how to setup a JSR-303 implementation as a Spring bean, keep reading.

Configuring a Bean Validation Implementation

Spring provides full support for the JSR-303 Bean Validation API.This includes convenient support for boot strapping a JSR-303 implementation as a Spring bean. This allows for a javax. validation. Validator Factory or javax. validation. Validator to be injected wherever validation is needed in your application.

Use the LocalValidatorFactoryBean to configure a default JSR-303 Validator as a Spring bean:
<bean id="validator"
class="org.spring frame work.validation.beanvalidation.LocalValidatorFactoryBean"/>

The basic configuration above will trigger JSR-303 to initialize using its default bootstrap mechanism. A JSR-303 provider, such as Hibernate Validator, is expected to be present in the classpath and will be detected automatically.

Injecting a Validator

LocalValidatorFactoryBean implements both javax.validation.ValidatorFactory and javax.validation. Validator, as well as Spring's org. spring frame work. validation. Validator.You may inject a reference to either of these interfaces into beans that need to invoke validation logic.

Inject a reference to javax.validation.Validator if you prefer to work with the JSR-303 API directly:

import javax.validation.Validator;
@Service
public class MyService {
@Autowired
private Validator validator;

Inject a reference to org.spring frame work.validation.Validator if your bean requires the Spring Validation API:

import org.springframework.validation.Validator;
@Service
public class MyService {
@Autowired
private Validator validator;
}

Configuring Custom Constraints

Each JSR-303 validation constraint consists of two parts.First, a @Constraint annotation that declares the constraint and its configurable properties. Second, an implementation of the javax. validation. Constraint Validator interface that implements the constraint's behavior.

To associate a declaration with an implementation, each @Constraint annotation references a corresponding Validation Constraint implementation class.At runtime, a Constraint Validator Factory instantiates the referenced implementation when the constraint annotation is encountered in your domain model.By default, the Loca Validator Factory Bean configures a Spring Constraint Validator Factory that uses Spring to create Constraint Validator instances.This allows your custom Constraint Validators to benefit from dependency injection like any other Spring bean.

Shown below is an example of a custom @Constraint declaration, followed by an associated ConstraintValidator implementation that uses Spring for dependency injection:

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MyConstraintValidator.class)
public @interface MyConstraint {
}
import javax.validation.ConstraintValidator;
public class MyConstraintValidator implements ConstraintValidator {
@Autowired;
private Foo aDependency;
...
}

As you can see, a ConstraintValidator implementation may have its dependencies @Autowired like any other Spring bean.

Additional Configuration Options

The default Local Valid ator Factory Bean configuration should prove sufficient for most cases. There are a number of other configuration options for various JSR-303 constructs, from message interpolation to traversal resolution. See the JavaDocs of Local Valid ator Factory Bean for more information on these options.

Configuring a DataBinder

Since Spring 3, a DataBinder instance can be configured with a Validator.Once configured, the Validator may be invoked by calling binder.validate(). Any validation Errors are automatically added to the binder's BindingResult.

When working with the DataBinder programatically, this can be used to invoke validation logic after binding to a target object:

Foo target = new Foo();
DataBinder binder = new DataBinder(target);
binder.setValidator(new FooValidator());
// bind to the target object
binder.bind(propertyValues);
// validate the target object
binder.validate();
// get BindingResult that includes any validation errors
BindingResult results = binder.getBindingResult();

Spring MVC 3 Validation

Beginning with Spring 3, Spring MVC has the ability to automatically validate @Controller inputs.In previous versions it was up to the developer to manually invoke validation logic.

Triggering @Controller Input Validation

To trigger validation of a @Controller input, simply annotate the input argument as @Valid:

@Controllerpublic class MyController {
@RequestMapping("/foo", method=RequestMethod.POST)
public void processFoo(@Valid Foo foo) { /* ... */ }

pring MVC will validate a @Valid object after binding so-long as an appropriate Validator has been configured.

Configuring a Validator for use by Spring MVC

The Validator instance invoked when a @Valid method argument is encountered may be configured in two ways. First, you may call binder.setValidator(Validator) within a @Controller's @InitBinder callback.This allows you to configure a Validator instance per @Controller class:

@Controller
public class MyController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new FooValidator());
}
@RequestMapping("/foo", method=RequestMethod.POST)
public void processFoo(@Valid Foo foo) { ... }
}

Configuring a JSR-303 Validator for use by Spring MVC
With JSR-303, a single javax.validation.Validator instance typically validates all model objects that declare validation constraints. To configure a JSR-303-backed Validator with Spring MVC, simply add a JSR-303 Provider, such as Hibernate Validator, to your classpath.Spring MVC will detect it and automatically enable JSR-303 support across all Controllers.

With this minimal configuration, anytime a @Valid @Controller input is encountered, it will be validated by the JSR-303 provider. JSR-303, in turn, will enforce any constraints declared against the input.Any ConstraintViolations will automatically be exposed as errors in the BindingResult renderable by standard Spring MVC form tags.


All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

Java-Springs Topics