Spring Framework Documentation
Validation, Data Binding, and Type Conversion
1.1 Introduction
JSR-303/JSR-349 Bean Validation
Spring Framework 4.0 supports Bean Validation 1.0 (JSR-303) and Bean Validation 1.1 (JSR-349) in terms of setup support,also adapting it to Springrsquo;s Validator interface.
An application can choose to enable Bean Validation once globally,as described in Spring Validation,and use it exclusively for all validation needs.
An application can also register additional Spring Validator instances per DataBinder instance,as described in Configuring a DataBinder.This may be useful for plugging in validation logic without the use of annotations.
There are pros and cons for considering validation as business logic,and Spring offers a design for validation(and data binding)that does not exclude either one of them.Specifically validation should not be tied to the web tier,should be easy to localize and it should be possible to plug in any validator available.Considering the above,Spring has come up with a Validator interface that is both basic and eminently usable in every layer of an application.
Data binding is useful for allowing user input to be dynamically bound to the domain model of an application(or whatever objects you use to process user input).Spring provides the so-called DataBinder to do exactly that.The Validator and the DataBinder make up the validation package,which is primarily used in but not limited to the MVC framework.
The BeanWrapper is a fundamental concept in the Spring Framework and is used in a lot of places.However,you probably will not have the need to use the BeanWrapper directly.Because this is reference documentation however,we felt that some explanation might be in order.We will explain the BeanWrapper in this chapter since,if you were going to use it at all,you would most likely do so when trying to bind data to objects.
Springrsquo;s DataBinder and the lower-level BeanWrapper both use PropertyEditors to parse and format property values.The PropertyEditor concept is part of the JavaBeans specification,and is also explained in this chapter.Spring 3 introduces a 'core.convert' package that provides a general type conversion facility,as well as a higher-level 'format' package for formatting UI field values.These new packages may be used as simpler alternatives to PropertyEditors,and will also be discussed in this chapter.
1.2 Validation using Springrsquo;s Validator interface
Spring features a Validator interface that you can use to validate objects. The Validator interface works using an Errors object so that while validating,validators can report validation failures to the Errors object.
Letrsquo;s consider a small data object:
public class Person {
private String name;
private int age;
// the usual getters and setters...
}
Wersquo;re going to provide validation behavior for the Person class by implementing the following two methods of the org.springframework.validation.Validator interface:
supports(Class)-Can this Validator validate instances of the supplied Class?
validate(Object,org.springframework.validation.Errors)-validates the given object and in case of validation errors,registers those with the given Errors object.
Implementing a Validator is fairly straightforward,especially when you know of the ValidationUtils helper class that the Spring Framework also provides.
public class PersonValidator implements Validator {
/**
* This Validator validates *just* Person instances
*/
public boolean supports(Class clazz) {
return Person.class.equals(clazz);
}
public void validate(Object obj, Errors e) {
ValidationUtils.rejectIfEmpty(e, 'name', 'name.empty');
Person p = (Person) obj;
if (p.getAge() lt; 0) {
e.rejectValue('age', 'negativevalue');
} else if (p.getAge() gt; 110) {
e.rejectValue('age', 'too.darn.old');
}
}
}
As you can see,the static rejectIfEmpty(..) method on the ValidationUtils class is used to reject the #39;name#39; property if it is null or the empty string.Have a look at the ValidationUtils javadocs to see what functio-nality it provides besides the example shown previously.
While it is certainly possible to implement a single Validator class to validate each of the nested objects in a rich object,it may be better to encapsulate the validation logic for each nested class of object in its own Validator implementation.A simple example of a #39;rich#39; object would be a Customer that is composed of two String properties(a first and second name)and a complex Address object.Address objects may be used independently of Customer objects,and so a distinct AddressValidator has been implemented.If you want your CustomerValidator to reuse the logic contained within the AddressValidator class without resorting to copy- and-paste,you can dependency-inject or instantiate an AddressValidator within your CustomerValidator,and use it like so:
public class CustomerValidator implements Validator {
private final Validator addressValidator;
public CustomerValidator(Validator addressValidator) {
if (addressValidator == null) {
throw new
全文共35935字,剩余内容已隐藏,支付完成后下载完整资料
Spring框架文档
验证,数据绑定和类型转换
1.1介绍
JSR-303/JSR-349 Bean验证
Spring Framework 4.0在安装支持方面支持Bean Validation 1.0(JSR-303)和Bean Validation 1.1(JSR-349),并将其适配到Spring的验证器接口。
如Spring验证中所述,应用程序可以选择全局使用Bean验证,并专门用于所有验证需求。
应用程序还可以为每个DataBinder实例注册额外的Spring验证器实例,如配置DataBinder中所述。这对于插入验证逻辑而不使用注释可能是有用的。
将验证视为业务逻辑有优点和缺点,Spring提供了验证(和数据绑定)设计,不排除其中任何一个。具体的验证不应该依赖于Web层,应该易于本地化,它应该可以在任何可用的验证堵塞。考虑到上述情况,Spring已经提出了一个验证器接口,该接口在应用程序的每一层都是基本的和显着的可用的。
数据绑定对于允许用户输入动态绑定到应用程序的域模型(或用于处理用户输入的任何对象)很有用。Spring提供了所谓的DataBinder来完成这件事。验证器和DataBinder组成了验证包,主要用于但不限于MVC框架。
BeanWrapper是Spring框架中的一个基本概念,并在很多地方使用。但是,您可能不需要直接使用BeanWrapper。因为这是参考文件,所以我们觉得有些解释可能是按顺序的。我们将在本章中解释BeanWrapper,因为如果您打算使用它,那么在尝试将数据绑定到对象时很可能会这样做。
Spring的DataBinder和较低级的BeanWrapper都使用属性编辑器来解析和格式化属性值。属性编辑器概念是JavaBeans规范的一部分,本章也对此进行了说明。Spring3引入了一个“core.convert”包,它提供了一个通用的类型转换工具,以及一个用于格式化UI字段值的高级“格式”包。这些新软件包可以作为属性编辑器的简单替代品,本章也将对此进行讨论。
1.2使用Spring的验证器接口进行验证
Spring提供了一个验证器接口,您可以使用它来验证对象。验证器接口使用错误对象工作,以便在验证时验证器可以将验证失败报告给错误对象。
我们来考虑一个小数据对象:
public class Person {
private String name;
private int age;
// the usual getters and setters...
}
我们将通过实现org.springframework.validation.Validator接口的以下两个方法来为Person类提供验证行为:
支持(类) - 此验证器可否验证提供的类的实例?
验证(Object,org.springframework.validation.Errors)- 验证给定的对象,并在验证错误的情况下,注册给定的错误对象。
实现验证器非常简单,特别是当您了解Spring框架也提供的ValidationUtils助手类时。
public class PersonValidator implements Validator {
/**
* This Validator validates *just* Person instances
*/
public boolean supports(Class clazz) {
return Person.class.equals(clazz);
}
public void validate(Object obj, Errors e) {
ValidationUtils.rejectIfEmpty(e, 'name', 'name.empty');
Person p = (Person) obj;
if (p.getAge() lt; 0) {
e.rejectValue('age', 'negativevalue');
} else if (p.getAge() gt; 110) {
e.rejectValue('age', 'too.darn.old');
}
}
}
如您所见,ValidationUtils类上的静态rejectIfEmpty(..)方法用于在“name”属性为空或空字符串时拒绝该属性。查看ValidationUtils javadoc以查看除前面所示示例之外它提供的功能。
尽管可以实现一个验证器类来验证丰富对象中的每个嵌套对象,但最好是将它的每个嵌套类的对象的验证逻辑封装在它自己的验证器实现中。“富”对象的一个简单示例是由两个字符串属性(第一个和第二个名称)和一个复杂的地址对象组成的顾客。Address对象可以独立于顾客对象使用,因此已经实现了一个独特的地址验证器。如果您希望您的顾客验证器重复使用地址验证器类中包含的逻辑而无需复制粘贴,则可以在您的顾客验证器中依赖注入或实例化地址验证器,并像下面这样使用它:
public class CustomerValidator implements Validator {
private final Validator addressValidator;
public CustomerValidator(Validator addressValidator) {
if (addressValidator == null) {
throw new IllegalArgumentException('The supplied [Validator] is '
'required and must not be null.');
}
if (!addressValidator.supports(Address.class)) {
throw new IllegalArgumentException('The supplied [Validator] must '
'support the validation of [Address] instances.');
}
this.addressValidator = addressValidator;
}
/**
* This Validator validates Customer instances, and any subclasses of Customer too
*/
public boolean supports(Class clazz) {
return Customer.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, 'firstName', 'field.required');
ValidationUtils.rejectIfEmptyOrWhitespace(errors, 'surname', 'field.required');
Customer customer = (Customer) target;
try {
errors.pushNestedPath('address');
ValidationUtils.invokeValidator(this.addressValidator, customer.getAddress(), errors);
} finally {
errors.popNestedPath();
}
}
}
将验证错误报告给传递给验证器的错误对象。在Spring Web MVC的情况下,您可以使用lt;spring:bind /gt;标签检查错误消息,但当然您也可以自己检查错误对象。有关它提供的方法的更多信息可以在javadocs中找到。
1.3将代码解析为错误消息
我们已经讨论过数据绑定和验证。输出与验证错误相对应的消息是我们需要讨论的最后一件事。在上面的例子中,我们拒绝了名字和年龄段。如果我们要通过使用消息来源输出错误消息,我们将使用我们在拒绝字段(本例中为#39;name#39;和#39;age#39;)时给出的错误代码。当您从错误接口调用(直接或间接使用ValidationUtils类)rejectValue或其他拒绝方法时,基础实现不仅会注册您通过的代码,还会注册一些其他错误代码。它注册的错误代码由使用的MessageCodesResolver决定。默认情况下,使用DefaultMessageCodesResolver,例如,它不仅会使用您提供的代码注册消息,还会使用包含您传递给拒绝方法的字段名称的消息。因此,如果您拒绝使用rejectValue(“age”,“too.darn.old”)的字段,除了too.darn.old代码外,Spring还会注册too.darn.old.age和too.darn.old .age.int(所以第一个将包含字段名称,第二个将包含字段的类型),这是为了方便开发人员定位错误消息等。
1.4 Bean操作和BeanWrapper
org.springframework.beans包遵循Oracle提供的JavaBeans标准。JavaBean只是一个带有默认无参构造函数的类,它遵循一个命名约定,其中一个名为bingoMadness的属性将具有setter方法setBingoMadness(..)和getter方法getBingoMadness()。有关JavaBeans和规范的更多信息,请参阅Oracle网站(javabeans)。
Bean包中一个相当重要的类是BeanWrapper接口及其相应的实现(BeanWrapperImpl)。从javadocs引用,BeanWrapper提供了设置和获取属性值(单独或批量),获取属性描述符和查询属性以确定它们是否可读或可写的功能。此外,BeanWrapper提供了对嵌套属性的支持,可以将子属性的属性设置为无限深度。然后,BeanWrapper支持添加标准JavaBeans PropertyChangeListeners和VetoableChangeListeners,而无需在目标类中支持代码。最后但并非最不重要的是,BeanWrapper提供了对设置索引属性的支持。BeanWrapper通常不直接由应用程序代码使用,而是由DataBinder和BeanFacto
全文共19802字,剩余内容已隐藏,支付完成后下载完整资料
资料编号:[14763],资料为PDF文档或Word文档,PDF文档可免费转换为Word
