项目作者: infobip

项目描述 :
Library which provides new features on top of Hibernate Validator and Spring Boot Validation starter.
高级语言: Java
项目地址: git://github.com/infobip/infobip-bean-validation.git
创建时间: 2017-10-03T13:14:40Z
项目社区:https://github.com/infobip/infobip-bean-validation

开源协议:Apache License 2.0

下载


Infobip Bean Validation


Maven Central
Coverage Status

Library which provides new features on top of Hibernate Validator and Spring Boot Validation starter.

Contents

  1. Features and examples
  2. Requirements
  3. Contributing
  4. License

Features and examples:

Basic:

  • Auto configuration - no manual configuration required
  • predefined validation groups - Create, Update, Delete
  • predefined validation sequence - ExpensiveSequence
  • Out of the box composed annotations: @ValidatedService, @ValidatedRestController

ConstraintViolationException mapping:

To remap all ConstraintViolationExceptions to a custom exception simply declare a bean of ConstraintViolationExceptionMapper type:

  1. @Bean
  2. public ConstraintViolationExceptionMapper<IllegalArgumentException> constraintViolationExceptionMapper() {
  3. return e -> new IllegalArgumentException(e.getMessage());
  4. }

Hibernate Validator Configuration Strategy:

By defining a bean of type HibernateConfigurationStrategy you can programmatically alter Hibernate Validator configuration:

  1. @Bean
  2. public HibernateValidatorConfigurationStrategy hibernateValidatorConfigurationStrategy() {
  3. return configuration -> configuration.clockProvider(Clock::systemUTC);
  4. }

SimpleConstraintValidator:

Bean Validation’s ConstraintValidator defines two abstract methods, initialize(A constraintAnnotation) and
isValid(T value, ConstraintValidatorContext context).
For most cases, initialize is not used and is implemented as empty method. Also, isValid expects you to treat null
value as valid. Both of these shortcomings are handled by SimpleConstraintValidator which is a FunctionalInterface
(lambdas!) and only requires you to implement isValid(T value) (value passed to implementation is never null).
An example of an implementation using ConstraintValidator:

  1. @Component
  2. public class FileNameValidator implements ConstraintValidator<FileName, String> {
  3. private static final char[] forbiddenCharacters = ...;
  4. @Override
  5. public void initialize(FileName constraintAnnotation) {
  6. }
  7. @Override
  8. public boolean isValid(String value, ConstraintValidatorContext context) {
  9. if (value == null) {
  10. return true;
  11. }
  12. return !StringUtils.containsAny(value, forbiddenCharacters);
  13. }
  14. }

As you can see, null check and initialize method implementation make a lot of useless noise.
Same example using SimpleConstraintValidator:

  1. @Component
  2. public class FileNameValidator implements SimpleConstraintValidator<FileName, String> {
  3. private static final char[] forbiddenCharacters = ...;
  4. @Override
  5. public boolean isValid(String value) {
  6. return !StringUtils.containsAny(value, forbiddenCharacters);
  7. }
  8. }

Validator bean injection:

This feature is provided by Spring and details can be found in official Spring documentation.
Example:

  1. @Component
  2. public class ValidExpirationTimeValidator implements SimpleConstraintValidator<ValidExpirationTime, Date> {
  3. private final Clock clock;
  4. public ValidExpirationTimeValidator(Clock clock) {
  5. this.clock = clock;
  6. }
  7. @Override
  8. public boolean isValid(Date value) {
  9. ... validation logic that uses injected clock
  10. }
  11. }

Decoupling of validation annotations and validators:

This feature is provided by Hibernate Validator and details can be found in official Hibernate Validator documentation.
Used for use cases where you don’t want to provide a default implementation for your custom validation annotation and want to register it programmatically. For example, validator and validation annotation are in different artifacts.

For example, lets say we have a custom validation annotation MustNotBeTopSecret (note the empty validatedBy) and validator MustNotBeTopSecretValidator:

Annotation:

  1. @Target(ElementType.FIELD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Constraint(validatedBy = {}) // EMPTY!
  4. @Documented
  5. public @interface MustNotBeTopSecret {
  6. String message() default "must not be top secret";
  7. Class<?>[] groups() default {};
  8. Class<? extends Payload>[] payload() default {};
  9. }

Validator:

  1. @Component
  2. public class MustNotBeTopSecretValidator implements ConstraintValidator<MustNotBeTopSecret, String> {
  3. private final TopSecretService topSecretService;
  4. @Autowired
  5. public MustNotBeTopSecretValidator(TopSecretService topSecretService) {
  6. this.topSecretService = topSecretService;
  7. }
  8. ... isValid and initialize implementations
  9. }

Custom validators are automatically injected into Hibernate Validator Configuration, here’s an example of how you’d do it manually:

  1. @Bean
  2. public HibernateConfigurationStrategy hibernateConfigurationStrategy() {
  3. return configuration -> configuration.createConstraintMapping()
  4. .constraintDefinition(MustNotBeTopSecret.class)
  5. .validatedBy(MustNotBeTopSecretValidator.class);
  6. }

Requirements:

  • Java 17
  • Hibernate Validator
  • Spring Boot (without Boot you will have to import BeanValidationAutoConfiguration manually)

Contributing

If you have an idea for a new feature or want to report a bug please use the issue tracker.

Pull requests are welcome!

License

This library is licensed under the Apache License, Version 2.0.