您的位置:首页 > 编程语言 > Java开发

Java bean validation 规范与参考实现

2014-08-11 13:54 267 查看
http://colobu.com/2014/08/08/Java-bean-validation-spec-and-framework/

JSR 303 – Bean Validation 是一个数据验证的规范。 2009年11月正式发布最终版本。

在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情。应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的。在通常的情况下,应用程序是分层的,比如表现层,业务层,持久化层等,很多时候同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余和一些管理的问题,比如说语义的一致性等。为了避免这样的情况发生,最好是将验证逻辑与相应的域模型进行绑定,为各个层提供统一的数据校验。

Bean Validation 为 JavaBean 验证定义了相应的元数据模型和 API。缺省的元数据是 Java Annotations,通过使用 XML 可以对Java注解信息进行覆盖和扩展。在应用程序中,通过使用 Bean Validation 或是你自己定义的 constraint,例如 @NotNull, @Max, @ZipCode, 就可以确保数据模型(JavaBean)的正确性。在JSR303规范中,constraint 可以附加到字段,getter 方法,类或者接口上面。对于一些特定的需求,用户可以很容易的开发定制化的
constraint。Bean Validation 是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。

Hibernate Validator 4.0是 JSR 303 的参考实现。

IBM developerWorks网站有一篇很好的文章介绍它。

JSR 349是Bean Validation 1.1规范,根据社区的反馈对JSR 303进行了优化和加强。 可以点击这里查看细节。

主要围绕一下方面进行工作。

集成其它最新发布的JSR

JAX-RS: 对HTTP method进行参数和返回值的校验
JAXB: 集成JAXB.
JPA: 提升JPA的集成
CDI: 允许CDI风格的注入
CDI: 集成方法级别的校验
EJB: 集成方法级别的校验
JSF: 集成JSF

Hibernate Validator 5.x 是Bean Validation 1.1参考实现。

hibernate validator官方文档提供了注解的列表。

AnnotationSupported data typesUseHibernate metadata impact
@AssertFalse
Boolean
,
boolean
Checks that the annotated element is
false
None
@AssertTrue
Boolean
,
boolean
Checks that the annotated element is
true
None
@DecimalMax(value=,
inclusive=)
BigDecimal
,
BigInteger
,
CharSequence
,
byte
,
short
,
int
,
long
and the respective wrappers of the primitive types; Additionally supported by HV: any sub-type of
Number
Checks whether the annotated value is less than the specified maximum, when
inclusive=false
. Otherwise whether the value is less than or equal to the specified maximum. The parameter
value
is the string representation of the max value according to the
BigDecimal
string representation.
None
@DecimalMin(value=,
inclusive=)
BigDecimal
,
BigInteger
,
CharSequence
,
byte
,
short
,
int
,
long
and the respective wrappers of the primitive types; Additionally supported by HV: any sub-type of
Number
Checks whether the annotated value is larger than the specified minimum, when
inclusive=false
. Otherwise whether the value is larger than or equal to the specified minimum. The parameter
value
is the string representation of the min value according to the
BigDecimal
string representation.
None
@Digits(integer=,
fraction=)
BigDecimal
,
BigInteger
,
CharSequence
,
byte
,
short
,
int
,
long
and the respective wrappers of the primitive types; Additionally supported by HV: any sub-type of
Number
Checks whether the annoted value is a number having up to
integer
digits and
fraction
fractional digits
Defines column precision and scale
@Future
java.util.Date
, supported by HV, if the

Joda Time date/time API is on the class path: any implementations of
ReadablePartial
and
ReadableInstant
Checks whether the annotated date is in the futureNone
@Max(value=)
BigDecimal
,
BigInteger
,
byte
,
short
,
int
,
long
and the respective wrappers of the primitive types; Additionally supported by HV: any sub-type of
CharSequence
(the numeric value represented by the character sequence is evaluated), any sub-type of
Number
Checks whether the annotated value is less than or equal to the specified maximumAdds a check constraint on the column
@Min(value=)
BigDecimal
,
BigInteger
,
byte
,
short
,
int
,
long
and the respective wrappers of the primitive types; Additionally supported by HV: any sub-type of
CharSequence
(the numeric value represented by the char sequence is evaluated), any sub-type of
Number
Checks whether the annotated value is higher than or equal to the specified minimumAdds a check constraint on the column
@NotNull
Any typeChecks that the annotated value is not
null.
Column(s) are not nullable
@Null
Any typeChecks that the annotated value is
null
None
@Past
java.util.Date
,
java.util.Calendar
; Additionally date/time API is on the class path: any implementations of
ReadablePartial
and
ReadableInstant
Checks whether the annotated date is in the pastNone
@Pattern(regex=,
flag=)
CharSequence
Checks if the annotated string matches the regular expression
regex
considering the given flag
match
None
@Size(min=, max=)
CharSequence
,
Collection
,
Map
and
arrays
Checks if the annotated element’s size is between min and max (inclusive)Column length will be set to
max
@Valid
Any non-primitive typePerforms validation recursively on the associated object. If the object is a collection or an array, the elements are validated recursively. If the object is a map, the value elements are validated recursively.None
另外,Hibernate提供了额外的注解:

AnnotationSupported data typesUseHibernate metadata impact
@CreditCardNumber(ignoreNonDigitCharacters=)
CharSequence
Checks that the annotated character sequence passes the Luhn checksum test. Note, this validation aims to check for user mistakes, not credit card validity! See also

Anatomy of Credit Card Numbers.
ignoreNonDigitCharacters
allows to ignore non digit characters. The default is
false
.
None
@EAN
CharSequence
Checks that the annotated character sequence is a valid

EAN barcode.
type
determines the type of barcode. The default is EAN-13.
None
@Email
CharSequence
Checks whether the specified character sequence is a valid email address. The optional parameters
regexp
and
flags
allow to specify an additional regular expression (including regular expression flags) which the email must match.
None
@Length(min=, max=)
CharSequence
Validates that the annotated character sequence is between
min
and
max
included
Column length will be set to
max
@LuhnCheck(
startIndex=,

endIndex=,
checkDigitIndex=,

ignoreNonDigitCharacters=)
CharSequence
Checks that the digits within the annotated character sequence pass the Luhn checksum algorithm (see also

Luhn algorithm).
startIndex
and
endIndex
allow to only run the algorithm on the specified sub-string.
checkDigitIndex
allows to use an arbitrary digit within the character sequence as the check digit. If not specified it is assumed that the check digit is part of the specified range. Last but not least,
ignoreNonDigitCharacters
allows to ignore non digit characters.
None
@Mod10Check(multiplier=,

weight=, startIndex=,
endIndex=,

checkDigitIndex=,
ignoreNonDigitCharacters=)
CharSequence
Checks that the digits within the annotated character sequence pass the generic mod 10 checksum algorithm.
multiplier
determines the multiplier for odd numbers (defaults to 3),
weight
the weight for even numbers (defaults to 1).
startIndex
and
endIndex
allow to only run the algorithm on the specified sub-string.
checkDigitIndex
allows to use an arbitrary digit within the character sequence as the check digit. If not specified it is assumed that the check digit is part of the specified range. Last but not least,
ignoreNonDigitCharacters
allows to ignore non digit characters.
None
@Mod11Check(threshold=,

startIndex=, endIndex=,
checkDigitIndex=,

ignoreNonDigitCharacters=,
treatCheck10As=,
treatCheck11As=)
CharSequence
Checks that the digits within the annotated character sequence pass the mod 11 checksum algorithm.
threshold
specifies the threshold for the mod11 multiplier growth; if no value is specified the multiplier will grow indefinitely.
treatCheck10As
and
treatCheck11As
specify the check digits to be used when the mod 11 checksum equals 10 or 11, respectively. Default to X and 0, respectively.
startIndex
,
endIndex
a
checkDigitIndex
and
ignoreNonDigitCharacters
carry the same semantics as in
@Mod10Check
.
None
@NotBlank
CharSequence
Checks that the annotated character sequence is not null and the trimmed length is greater than 0. The difference to
@NotEmpty
is that this constraint can only be applied on strings and that trailing whitespaces are ignored.
None
@NotEmpty
CharSequence
,
Collection
,
Map
and arrays
Checks whether the annotated element is not
null
nor empty
None
@Range(min=, max=)
BigDecimal
,
BigInteger
,
CharSequence
,
byte
,
short
,
int
,
long
and the respective wrappers of the primitive types
Checks whether the annotated value lies between (inclusive) the specified minimum and maximumNone
@SafeHtml(whitelistType=,

additionalTags=, additionalTagsWithAttributes=)
CharSequence
Checks whether the annotated value contains potentially malicious fragments such as
<script/>
. In order to use this constraint, the
jsoup library must be part of the class path.

With the
whitelistType
attribute a predefined whitelist type can be chosen which can be refined via
additionalTags
or
additionalTagsWithAttributes
. The former allows to add tags without any attributes, whereas the latter allows to specify tags and optionally allowed attributes using the annotation
@SafeHtml.Tag
.

None
@ScriptAssert(lang=,

script=, alias=)
Any typeChecks whether the given script can successfully be evaluated against the annotated element. In order to use this constraint, an implementation of the Java Scripting API as defined by JSR 223 ("Scripting for the JavaTM
Platform") must part of the class path. The expressions to be evaluated can be written in any scripting or expression language, for which a JSR 223 compatible engine can be found in the class path.
None
@URL(protocol=,
host=, port=
regexp=, flags=)
CharSequence
Checks if the annotated character sequence is a valid URL according to RFC2396. If any of the optional parameters
protocol
,
host
or
port
are specified, the corresponding URL fragments must match the specified values. The optional parameters
regexp
and
flags
allow to specify an additional regular expression (including regular expression flags) which the URL must match.
None
你可以通过下面的代码校验带注解的Java Bean实例。

123456

Validator validator = Validation.byProvider( HibernateValidator.class )        .configure()        .failFast( true )        .buildValidatorFactory()        .getValidator();Set<ConstraintViolation<Car>> constraintViolations = validator.validate( anInstance );

在Spring中可以配置如下:

12345

<bean id="validator"    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">    <property name="providerClass"        value="org.hibernate.validator.HibernateValidator" /></bean>

Apache BVal提供了JSR 303另外一个实现。

1234

ValidatorFactory avf =            Validation.byProvider(ApacheValidationProvider.class).configure().buildValidatorFactory();Validator validator = avf.getValidator();Set<ConstraintViolation<Car>> constraintViolations = validator.validate( anInstance );

在Spring中可以配置如下:

12345

<bean id="validator"    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">    <property name="providerClass"        value="org.apache.bval.jsr303.ApacheValidationProvider" /></bean>

另外Apache还有一个较老的项目:Apache Commons Validator,提供了一些校验类。

12345678

DateValidator validator = DateValidator.getInstance();      // Validate/Convert the date      Date fooDate = validator.validate(fooString, "dd/MM/yyyy");      if (fooDate == null) {          // error...not a valid date          return;      }

依照carinae.net网站(http://carinae.net/2010/06/benchmarking-hibernate-validator-and-apache-beanvalidation-the-two-jsr-303-implementations/)的2010年的测试,

Apache bval性能要好于hibernate。 这么多年过去了,不知道现在的性能怎么样了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: