This commit is contained in:
Jonathan Cook
2019-10-23 15:01:44 +02:00
parent db85c8f275
commit 684ec0d2e3
20486 changed files with 1642483 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
.classpath
.project
.settings/
target/
bin/
+12
View File
@@ -0,0 +1,12 @@
## Java Bean Validation Examples
This module contains articles about Bean Validation.
### Relevant Articles:
- [Java Bean Validation Basics](https://www.baeldung.com/javax-validation)
- [Validating Container Elements with Bean Validation 2.0](https://www.baeldung.com/bean-validation-container-elements)
- [Method Constraints with Bean Validation 2.0](https://www.baeldung.com/javax-validation-method-constraints)
- [Difference Between @NotNull, @NotEmpty, and @NotBlank Constraints in Bean Validation](https://www.baeldung.com/java-bean-validation-not-null-empty-blank)
- [Javax BigDecimal Validation](https://www.baeldung.com/javax-bigdecimal-validation)
- [Grouping Javax Validation Constraints](https://www.baeldung.com/javax-validation-groups)
- [Javax Validations for Enums](https://www.baeldung.com/javax-validations-enums)
+61
View File
@@ -0,0 +1,61 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>javaxval</artifactId>
<version>0.1-SNAPSHOT</version>
<name>javaxval</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${validation-api.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>${javax.el.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<validation-api.version>2.0.1.Final</validation-api.version>
<hibernate-validator.version>6.0.13.Final</hibernate-validator.version>
<javax.el.version>3.0.0</javax.el.version>
<org.springframework.version>5.0.2.RELEASE</org.springframework.version>
<assertj.version>3.11.1</assertj.version>
</properties>
</project>
@@ -0,0 +1,93 @@
package org.baeldung.javaxval.beanvalidation;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
public class User {
@NotNull(message = "Name cannot be null")
private String name;
@AssertTrue
private boolean working;
@Size(min = 10, max = 200, message = "Number of characters should be in between 10 and 200 inclusive")
private String aboutMe;
@Min(value = 18, message = "Age should not be less than 18")
@Max(value = 150, message = "Age should not be more than 150")
private int age;
@Email(message = "Email should be valid")
private String email;
private List<@NotBlank String> preferences;
private LocalDate dateOfBirth;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isWorking() {
return working;
}
public void setWorking(boolean working) {
this.working = working;
}
public String getAboutMe() {
return aboutMe;
}
public void setAboutMe(String aboutMe) {
this.aboutMe = aboutMe;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Optional<@Past LocalDate> getDateOfBirth() {
return Optional.ofNullable(dateOfBirth);
}
public void setDateOfBirth(LocalDate dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<String> getPreferences() {
return preferences;
}
public void setPreferences(List<String> preferences) {
this.preferences = preferences;
}
}
@@ -0,0 +1,19 @@
package org.baeldung.javaxval.bigdecimal;
import java.math.BigDecimal;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Digits;
public class Invoice {
@DecimalMin(value = "0.0", inclusive = false)
@Digits(integer = 3, fraction = 2)
private BigDecimal price;
private String description;
public Invoice(BigDecimal price, String description) {
this.price = price;
this.description = description;
}
}
@@ -0,0 +1,66 @@
package org.baeldung.javaxval.container.validation;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.PositiveOrZero;
public class Customer {
@NotBlank(message = "Name cannot be empty")
private String name;
private List<@NotBlank(message = "Address must not be blank") String> addresses;
private Integer age;
@PositiveOrZero
private OptionalInt numberOfOrders;
@NotBlank
private Profile profile;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getAddresses() {
return addresses;
}
public void setAddresses(List<String> addresses) {
this.addresses = addresses;
}
public Optional<@Min(18) Integer> getAge() {
return Optional.ofNullable(age);
}
public void setAge(Integer age) {
this.age = age;
}
public OptionalInt getNumberOfOrders() {
return numberOfOrders;
}
public void setNumberOfOrders(OptionalInt numberOfOrders) {
this.numberOfOrders = numberOfOrders;
}
public Profile getProfile() {
return profile;
}
public void setProfile(Profile profile) {
this.profile = profile;
}
}
@@ -0,0 +1,19 @@
package org.baeldung.javaxval.container.validation;
import java.util.Map;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
public class CustomerMap {
private Map<@Email(message = "Must be a valid email") String, @NotNull Customer> customers;
public Map<String, Customer> getCustomers() {
return customers;
}
public void setCustomers(Map<String, Customer> customers) {
this.customers = customers;
}
}
@@ -0,0 +1,13 @@
package org.baeldung.javaxval.container.validation;
public class Profile {
private String companyName;
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
}
@@ -0,0 +1,17 @@
package org.baeldung.javaxval.container.validation.valueextractors;
import javax.validation.valueextraction.ExtractedValue;
import javax.validation.valueextraction.UnwrapByDefault;
import javax.validation.valueextraction.ValueExtractor;
import org.baeldung.javaxval.container.validation.Profile;
@UnwrapByDefault
public class ProfileValueExtractor implements ValueExtractor<@ExtractedValue(type = String.class) Profile> {
@Override
public void extractValues(Profile originalValue, ValueExtractor.ValueReceiver receiver) {
receiver.value(null, originalValue.getCompanyName());
}
}
@@ -0,0 +1,24 @@
package org.baeldung.javaxval.enums;
import java.util.Arrays;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.baeldung.javaxval.enums.constraints.CustomerTypeSubset;
import org.baeldung.javaxval.enums.demo.CustomerType;
public class CustomerTypeSubSetValidator implements ConstraintValidator<CustomerTypeSubset, CustomerType> {
private CustomerType[] subset;
@Override
public void initialize(CustomerTypeSubset constraint) {
this.subset = constraint.anyOf();
}
@Override
public boolean isValid(CustomerType value, ConstraintValidatorContext context) {
return value == null || Arrays.asList(subset)
.contains(value);
}
}
@@ -0,0 +1,33 @@
package org.baeldung.javaxval.enums;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.baeldung.javaxval.enums.constraints.EnumNamePattern;
public class EnumNamePatternValidator implements ConstraintValidator<EnumNamePattern, Enum<?>> {
private Pattern pattern;
@Override
public void initialize(EnumNamePattern constraintAnnotation) {
try {
pattern = Pattern.compile(constraintAnnotation.regexp());
} catch (PatternSyntaxException e) {
throw new IllegalArgumentException("Given regex is invalid", e);
}
}
@Override
public boolean isValid(Enum<?> value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
Matcher m = pattern.matcher(value.name());
return m.matches();
}
}
@@ -0,0 +1,25 @@
package org.baeldung.javaxval.enums;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public abstract class EnumSubSetValidator<T extends Annotation, U> implements ConstraintValidator<T, U> {
private U[] subset;
protected void initialize(U[] subset) {
this.subset = subset;
}
@Override
public boolean isValid(U value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
return Arrays.asList(subset)
.contains(value);
}
}
@@ -0,0 +1,11 @@
package org.baeldung.javaxval.enums;
import org.baeldung.javaxval.enums.constraints.CustomerTypeSubset;
import org.baeldung.javaxval.enums.demo.CustomerType;
public class InheritedCustomerTypeSubSetValidator extends EnumSubSetValidator<CustomerTypeSubset, CustomerType> {
@Override
public void initialize(CustomerTypeSubset constraint) {
super.initialize(constraint.anyOf());
}
}
@@ -0,0 +1,31 @@
package org.baeldung.javaxval.enums;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.baeldung.javaxval.enums.constraints.ValueOfEnum;
public class ValueOfEnumValidator implements ConstraintValidator<ValueOfEnum, CharSequence> {
private List<String> acceptedValues;
@Override
public void initialize(ValueOfEnum annotation) {
acceptedValues = Stream.of(annotation.enumClass()
.getEnumConstants())
.map(Enum::name)
.collect(Collectors.toList());
}
@Override
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
return acceptedValues.contains(value.toString());
}
}
@@ -0,0 +1,45 @@
package org.baeldung.javaxval.enums.constraints;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import org.baeldung.javaxval.enums.CustomerTypeSubSetValidator;
import org.baeldung.javaxval.enums.demo.CustomerType;
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = CustomerTypeSubSetValidator.class)
public @interface CustomerTypeSubset {
/**
* @return subset of CustomerType enum
*/
CustomerType[] anyOf();
/**
* @return the error message template
*/
String message() default "must be any of {anyOf}";
/**
* @return the groups the constraint belongs to
*/
Class<?>[] groups() default {};
/**
* @return the payload associated to the constraint
*/
Class<? extends Payload>[] payload() default {};
}
@@ -0,0 +1,45 @@
package org.baeldung.javaxval.enums.constraints;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import org.baeldung.javaxval.enums.EnumNamePatternValidator;
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = EnumNamePatternValidator.class)
public @interface EnumNamePattern {
/**
* @return the regular expression to match
*/
String regexp();
/**
* @return the error message template
*/
String message() default "must match \"{regexp}\"";
/**
* @return the groups the constraint belongs to
*/
Class<?>[] groups() default {};
/**
* @return the payload associated to the constraint
*/
Class<? extends Payload>[] payload() default {};
}
@@ -0,0 +1,44 @@
package org.baeldung.javaxval.enums.constraints;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import org.baeldung.javaxval.enums.ValueOfEnumValidator;
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = ValueOfEnumValidator.class)
public @interface ValueOfEnum {
/**
* @return class containing enum values to which this String should match
*/
Class<? extends Enum<?>> enumClass();
/**
* @return the error message template
*/
String message() default "must be any of enum {enumClass}";
/**
* @return the groups the constraint belongs to
*/
Class<?>[] groups() default {};
/**
* @return the payload associated to the constraint
*/
Class<? extends Payload>[] payload() default {};
}
@@ -0,0 +1,77 @@
package org.baeldung.javaxval.enums.demo;
import javax.validation.constraints.NotNull;
import org.baeldung.javaxval.enums.constraints.CustomerTypeSubset;
import org.baeldung.javaxval.enums.constraints.EnumNamePattern;
import org.baeldung.javaxval.enums.constraints.ValueOfEnum;
public class Customer {
@ValueOfEnum(enumClass = CustomerType.class)
private String customerTypeString;
@NotNull
@CustomerTypeSubset(anyOf = { CustomerType.NEW, CustomerType.OLD })
private CustomerType customerTypeOfSubset;
@EnumNamePattern(regexp = "NEW|DEFAULT")
private CustomerType customerTypeMatchesPattern;
public Customer() {
}
public Customer(String customerTypeString, CustomerType customerTypeOfSubset, CustomerType customerTypeMatchesPattern) {
this.customerTypeString = customerTypeString;
this.customerTypeOfSubset = customerTypeOfSubset;
this.customerTypeMatchesPattern = customerTypeMatchesPattern;
}
public String getCustomerTypeString() {
return customerTypeString;
}
public void setCustomerTypeString(String customerTypeString) {
this.customerTypeString = customerTypeString;
}
public CustomerType getCustomerTypeOfSubset() {
return customerTypeOfSubset;
}
public void setCustomerTypeOfSubset(CustomerType customerTypeOfSubset) {
this.customerTypeOfSubset = customerTypeOfSubset;
}
public CustomerType getCustomerTypeMatchesPattern() {
return customerTypeMatchesPattern;
}
public void setCustomerTypeMatchesPattern(CustomerType customerTypeMatchesPattern) {
this.customerTypeMatchesPattern = customerTypeMatchesPattern;
}
public static class Builder {
private String customerTypeString;
private CustomerType customerTypeOfSubset = CustomerType.NEW;
private CustomerType customerTypeMatchesPattern;
public Builder withCustomerTypeString(String customerTypeString) {
this.customerTypeString = customerTypeString;
return this;
}
public Builder withCustomerTypeOfSubset(CustomerType customerTypeOfSubset) {
this.customerTypeOfSubset = customerTypeOfSubset;
return this;
}
public Builder withCustomerTypeMatchesPattern(CustomerType customerTypeMatchesPattern) {
this.customerTypeMatchesPattern = customerTypeMatchesPattern;
return this;
}
public Customer build() {
return new Customer(customerTypeString, customerTypeOfSubset, customerTypeMatchesPattern);
}
}
}
@@ -0,0 +1,5 @@
package org.baeldung.javaxval.enums.demo;
public enum CustomerType {
NEW, OLD, DEFAULT
}
@@ -0,0 +1,18 @@
package org.baeldung.javaxval.javabeanconstraints.application;
import javax.validation.Validation;
import javax.validation.Validator;
import org.baeldung.javaxval.javabeanconstraints.entities.UserNotBlank;
public class Application {
public static void main(String[] args) {
Validator validator = Validation.buildDefaultValidatorFactory()
.getValidator();
UserNotBlank user = new UserNotBlank(" ");
validator.validate(user)
.stream()
.forEach(violation -> System.out.println(violation.getMessage()));
}
}
@@ -0,0 +1,22 @@
package org.baeldung.javaxval.javabeanconstraints.entities;
import javax.validation.constraints.NotBlank;
public class UserNotBlank {
@NotBlank(message = "Name is mandatory")
private final String name;
public UserNotBlank(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "User{" + "name=" + name + "}";
}
}
@@ -0,0 +1,22 @@
package org.baeldung.javaxval.javabeanconstraints.entities;
import javax.validation.constraints.NotEmpty;
public class UserNotEmpty {
@NotEmpty(message = "Name is mandatory")
private final String name;
public UserNotEmpty(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "User{" + "name=" + name + "}";
}
}
@@ -0,0 +1,22 @@
package org.baeldung.javaxval.javabeanconstraints.entities;
import javax.validation.constraints.NotNull;
public class UserNotNull {
@NotNull(message = "Name is mandatory")
private final String name;
public UserNotNull(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "User{" + "name=" + name + "}";
}
}
@@ -0,0 +1,38 @@
package org.baeldung.javaxval.methodvalidation;
import java.time.LocalDate;
import org.baeldung.javaxval.methodvalidation.model.Customer;
import org.baeldung.javaxval.methodvalidation.model.Reservation;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
@Configuration
@ComponentScan({ "org.baeldung.javaxval.methodvalidation.model" })
public class MethodValidationConfig {
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
@Bean("customer")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Customer customer(String firstName, String lastName) {
Customer customer = new Customer(firstName, lastName);
return customer;
}
@Bean("reservation")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Reservation reservation(LocalDate begin, LocalDate end, Customer customer, int room) {
Reservation reservation = new Reservation(begin, end, customer, room);
return reservation;
}
}
@@ -0,0 +1,26 @@
package org.baeldung.javaxval.methodvalidation.constraints;
import java.time.LocalDate;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;
@SupportedValidationTarget(ValidationTarget.PARAMETERS)
public class ConsistentDateParameterValidator implements ConstraintValidator<ConsistentDateParameters, Object[]> {
@Override
public boolean isValid(Object[] value, ConstraintValidatorContext context) {
if (value[0] == null || value[1] == null) {
return true;
}
if (!(value[0] instanceof LocalDate) || !(value[1] instanceof LocalDate)) {
throw new IllegalArgumentException("Illegal method signature, expected two parameters of type LocalDate.");
}
return ((LocalDate) value[0]).isAfter(LocalDate.now()) && ((LocalDate) value[0]).isBefore((LocalDate) value[1]);
}
}
@@ -0,0 +1,25 @@
package org.baeldung.javaxval.methodvalidation.constraints;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Constraint(validatedBy = ConsistentDateParameterValidator.class)
@Target({ METHOD, CONSTRUCTOR })
@Retention(RUNTIME)
@Documented
public @interface ConsistentDateParameters {
String message() default "End date must be after begin date and both must be in the future";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@@ -0,0 +1,25 @@
package org.baeldung.javaxval.methodvalidation.constraints;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Constraint(validatedBy = ValidReservationValidator.class)
@Target({ METHOD, CONSTRUCTOR })
@Retention(RUNTIME)
@Documented
public @interface ValidReservation {
String message() default "End date must be after begin date and both must be in the future, room number must be bigger than 0";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@@ -0,0 +1,33 @@
package org.baeldung.javaxval.methodvalidation.constraints;
import java.time.LocalDate;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.baeldung.javaxval.methodvalidation.model.Reservation;
public class ValidReservationValidator implements ConstraintValidator<ValidReservation, Reservation> {
@Override
public boolean isValid(Reservation reservation, ConstraintValidatorContext context) {
if (reservation == null) {
return true;
}
if (!(reservation instanceof Reservation)) {
throw new IllegalArgumentException("Illegal method signature, expected parameter of type Reservation.");
}
if (reservation.getBegin() == null || reservation.getEnd() == null || reservation.getCustomer() == null) {
return false;
}
return (reservation.getBegin()
.isAfter(LocalDate.now())
&& reservation.getBegin()
.isBefore(reservation.getEnd())
&& reservation.getRoom() > 0);
}
}
@@ -0,0 +1,41 @@
package org.baeldung.javaxval.methodvalidation.model;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.springframework.validation.annotation.Validated;
@Validated
public class Customer {
@Size(min = 5, max = 200)
private String firstName;
@Size(min = 5, max = 200)
private String lastName;
public Customer(@Size(min = 5, max = 200) @NotNull String firstName, @Size(min = 5, max = 200) @NotNull String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public Customer() {
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
@@ -0,0 +1,65 @@
package org.baeldung.javaxval.methodvalidation.model;
import java.time.LocalDate;
import javax.validation.Valid;
import javax.validation.constraints.Positive;
import org.baeldung.javaxval.methodvalidation.constraints.ConsistentDateParameters;
import org.baeldung.javaxval.methodvalidation.constraints.ValidReservation;
import org.springframework.validation.annotation.Validated;
@Validated
public class Reservation {
private LocalDate begin;
private LocalDate end;
@Valid
private Customer customer;
@Positive
private int room;
@ConsistentDateParameters
@ValidReservation
public Reservation(LocalDate begin, LocalDate end, Customer customer, int room) {
this.begin = begin;
this.end = end;
this.customer = customer;
this.room = room;
}
public LocalDate getBegin() {
return begin;
}
public void setBegin(LocalDate begin) {
this.begin = begin;
}
public LocalDate getEnd() {
return end;
}
public void setEnd(LocalDate end) {
this.end = end;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public int getRoom() {
return room;
}
public void setRoom(int room) {
this.room = room;
}
}
@@ -0,0 +1,53 @@
package org.baeldung.javaxval.methodvalidation.model;
import java.time.LocalDate;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.Future;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.baeldung.javaxval.methodvalidation.constraints.ConsistentDateParameters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
@Controller
@Validated
public class ReservationManagement {
@Autowired
private ApplicationContext applicationContext;
@ConsistentDateParameters
public void createReservation(LocalDate begin, LocalDate end, @NotNull Customer customer) {
// ...
}
public void createReservation(@NotNull @Future LocalDate begin, @Min(1) int duration, @NotNull Customer customer) {
// ...
}
public void createReservation(@Valid Reservation reservation) {
// ...
}
@NotNull
@Size(min = 1)
public List<@NotNull Customer> getAllCustomers() {
return null;
}
@Valid
public Reservation getReservationById(int id) {
return null;
}
}
@@ -0,0 +1,5 @@
package org.baeldung.javaxval.validationgroup;
public interface AdvanceInfo {
}
@@ -0,0 +1,5 @@
package org.baeldung.javaxval.validationgroup;
public interface BasicInfo {
}
@@ -0,0 +1,8 @@
package org.baeldung.javaxval.validationgroup;
import javax.validation.GroupSequence;
@GroupSequence({ BasicInfo.class, AdvanceInfo.class })
public interface CompleteInfo {
}
@@ -0,0 +1,110 @@
package org.baeldung.javaxval.validationgroup;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
public class RegistrationForm {
@NotBlank(groups = BasicInfo.class)
private String firstName;
@NotBlank(groups = BasicInfo.class)
private String lastName;
@Email(groups = BasicInfo.class)
private String email;
@NotBlank(groups = BasicInfo.class)
private String phone;
@NotBlank(groups = { BasicInfo.class, AdvanceInfo.class })
private String captcha;
@NotBlank(groups = AdvanceInfo.class)
private String street;
@NotBlank(groups = AdvanceInfo.class)
private String houseNumber;
@NotBlank(groups = AdvanceInfo.class)
private String zipCode;
@NotBlank(groups = AdvanceInfo.class)
private String city;
@NotBlank(groups = AdvanceInfo.class)
private String country;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getHouseNumber() {
return houseNumber;
}
public void setHouseNumber(String houseNumber) {
this.houseNumber = houseNumber;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getCaptcha() {
return captcha;
}
public void setCaptcha(String captcha) {
this.captcha = captcha;
}
}
@@ -0,0 +1 @@
org.baeldung.javaxval.container.validation.valueextractors.ProfileValueExtractor
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
@@ -0,0 +1,23 @@
package org.baeldung.javaxval;
import java.util.Locale;
import org.junit.AfterClass;
import org.junit.BeforeClass;
public abstract class LocaleAwareUnitTest {
private static Locale previousDefault;
@BeforeClass
public static void setupLocale() {
previousDefault = Locale.getDefault();
Locale.setDefault(Locale.US);
}
@AfterClass
public static void resetLocale() {
Locale.setDefault(previousDefault);
}
}
@@ -0,0 +1,124 @@
package org.baeldung.javaxval.beanvalidation;
import static org.junit.Assert.assertEquals;
import java.time.LocalDate;
import java.util.Collections;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.junit.Before;
import org.junit.Test;
public class ValidationIntegrationTest {
private Validator validator;
@Before
public void setup() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
private User createUser() {
User user = new User();
user.setName("John");
user.setWorking(true);
user.setAge(18);
return user;
}
@Test
public void ifNameIsNull_nameValidationFails() {
User user = new User();
user.setWorking(true);
user.setAboutMe("Its all about me!!");
user.setAge(50);
Set<ConstraintViolation<User>> violations = validator.validate(user);
assertEquals(violations.isEmpty(), false);
}
@Test
public void ifSizeNotInRange_aboutMeValidationFails() {
User user = new User();
user.setName("MyName");
user.setAboutMe("Its all about me!!");
user.setAge(50);
Set<ConstraintViolation<User>> violations = validator.validate(user);
assertEquals(violations.isEmpty(), false);
}
@Test
public void ifWorkingIsFalse_workingValidationFails() {
User user = new User();
user.setName("MyName");
user.setAboutMe("Its all about me!!");
user.setAge(50);
Set<ConstraintViolation<User>> violations = validator.validate(user);
assertEquals(violations.isEmpty(), false);
}
@Test
public void ifAgeNotRange_ageValidationFails() {
User user = new User();
user.setName("MyName");
user.setAboutMe("Its all about me!!");
user.setAge(8);
Set<ConstraintViolation<User>> violations = validator.validate(user);
assertEquals(violations.isEmpty(), false);
}
@Test
public void ifFnameNullAgeNotRangeAndWorkingIsFalse_validationFailsWithThreeErrors() {
User user = new User();
user.setAboutMe("Its all about me!!");
user.setAge(300);
Set<ConstraintViolation<User>> violations = validator.validate(user);
assertEquals(violations.isEmpty(), false);
assertEquals(violations.size(), 3);
}
@Test
public void givenInvalidEmail_thenValidationFails() {
User user = createUser();
user.setEmail("john");
Set<ConstraintViolation<User>> violations = validator.validate(user);
assertEquals(1, violations.size());
}
@Test
public void givenBlankPreference_thenValidationFails() {
User user = createUser();
user.setPreferences(Collections.singletonList(" "));
Set<ConstraintViolation<User>> violations = validator.validate(user);
assertEquals(1, violations.size());
}
@Test
public void givenEmptyOptional_thenValidationSucceeds() {
User user = createUser();
Set<ConstraintViolation<User>> violations = validator.validate(user);
assertEquals(0, violations.size());
}
@Test
public void givenPastDateOfBirth_thenValidationSuccess() {
User user = createUser();
user.setDateOfBirth(LocalDate.of(1980, 5, 20));
Set<ConstraintViolation<User>> violations = validator.validate(user);
assertEquals(0, violations.size());
}
}
@@ -0,0 +1,64 @@
package org.baeldung.javaxval.bigdecimal;
import static org.assertj.core.api.Assertions.assertThat;
import java.math.BigDecimal;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.baeldung.javaxval.LocaleAwareUnitTest;
import org.junit.BeforeClass;
import org.junit.Test;
public class InvoiceUnitTest extends LocaleAwareUnitTest {
private static Validator validator;
@BeforeClass
public static void setupValidatorInstance() {
validator = Validation.buildDefaultValidatorFactory()
.getValidator();
}
@Test
public void whenPriceIntegerDigitLessThanThreeWithDecimalValue_thenShouldGiveConstraintViolations() {
Invoice invoice = new Invoice(new BigDecimal(10.21), "Book purchased");
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> assertThat(action.getMessage()).isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)"));
}
@Test
public void whenPriceIntegerDigitLessThanThreeWithIntegerValue_thenShouldNotGiveConstraintViolations() {
Invoice invoice = new Invoice(new BigDecimal(10), "Book purchased");
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
assertThat(violations.size()).isEqualTo(0);
}
@Test
public void whenPriceIntegerDigitGreaterThanThree_thenShouldGiveConstraintViolations() {
Invoice invoice = new Invoice(new BigDecimal(1021.21), "Book purchased");
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> assertThat(action.getMessage()).isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)"));
}
@Test
public void whenPriceIsZero_thenShouldGiveConstraintViolations() {
Invoice invoice = new Invoice(new BigDecimal(000.00), "Book purchased");
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> assertThat(action.getMessage()).isEqualTo("must be greater than 0.0"));
}
@Test
public void whenPriceIsGreaterThanZero_thenShouldNotGiveConstraintViolations() {
Invoice invoice = new Invoice(new BigDecimal(100.50), "Book purchased");
Set<ConstraintViolation<Invoice>> violations = validator.validate(invoice);
assertThat(violations.size()).isEqualTo(0);
}
}
@@ -0,0 +1,90 @@
package org.baeldung.javaxval.container.validation;
import static org.junit.Assert.assertEquals;
import java.util.Collections;
import java.util.OptionalInt;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.baeldung.javaxval.container.validation.valueextractors.ProfileValueExtractor;
import org.junit.Before;
import org.junit.Test;
public class ContainerValidationIntegrationTest {
private Validator validator;
@Before
public void setup() {
ValidatorFactory factory = Validation.byDefaultProvider()
.configure()
.addValueExtractor(new ProfileValueExtractor())
.buildValidatorFactory();
validator = factory.getValidator();
}
@Test
public void whenEmptyAddress_thenValidationFails() {
Customer customer = new Customer();
customer.setName("John");
customer.setAddresses(Collections.singletonList(" "));
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertEquals(1, violations.size());
assertEquals("Address must not be blank", violations.iterator()
.next()
.getMessage());
}
@Test
public void whenInvalidEmail_thenValidationFails() {
CustomerMap map = new CustomerMap();
map.setCustomers(Collections.singletonMap("john", new Customer()));
Set<ConstraintViolation<CustomerMap>> violations = validator.validate(map);
assertEquals(1, violations.size());
assertEquals("Must be a valid email", violations.iterator()
.next()
.getMessage());
}
@Test
public void whenAgeTooLow_thenValidationFails() {
Customer customer = new Customer();
customer.setName("John");
customer.setAge(15);
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertEquals(1, violations.size());
}
@Test
public void whenAgeNull_thenValidationSucceeds() {
Customer customer = new Customer();
customer.setName("John");
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertEquals(0, violations.size());
}
@Test
public void whenNumberOrdersValid_thenValidationSucceeds() {
Customer customer = new Customer();
customer.setName("John");
customer.setNumberOfOrders(OptionalInt.of(1));
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertEquals(0, violations.size());
}
@Test
public void whenProfileCompanyNameBlank_thenValidationFails() {
Customer customer = new Customer();
customer.setName("John");
Profile profile = new Profile();
profile.setCompanyName(" ");
customer.setProfile(profile);
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertEquals(1, violations.size());
}
}
@@ -0,0 +1,45 @@
package org.baeldung.javaxval.enums;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.baeldung.javaxval.enums.demo.Customer;
import org.baeldung.javaxval.enums.demo.CustomerType;
import org.baeldung.javaxval.enums.demo.CustomerUnitTest;
import org.junit.BeforeClass;
import org.junit.Test;
public class CustomerTypeSubSetValidatorUnitTest {
private static Validator validator;
@BeforeClass
public static void setupValidatorInstance() {
validator = Validation.buildDefaultValidatorFactory()
.getValidator();
}
@Test
public void whenEnumAnyOfSubset_thenShouldNotReportConstraintViolations() {
Customer customer = new Customer.Builder().withCustomerTypeOfSubset(CustomerType.NEW)
.build();
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertThat(violations.isEmpty()).isTrue();
}
@Test
public void whenEnumNotAnyOfSubset_thenShouldGiveOccurrenceOfConstraintViolations() {
Customer customer = new Customer.Builder().withCustomerTypeOfSubset(CustomerType.DEFAULT)
.build();
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertThat(violations.size()).isEqualTo(1);
assertThat(violations).anyMatch(CustomerUnitTest.havingPropertyPath("customerTypeOfSubset")
.and(CustomerUnitTest.havingMessage("must be any of [NEW, OLD]")));
}
}
@@ -0,0 +1,54 @@
package org.baeldung.javaxval.enums;
import static org.assertj.core.api.Assertions.assertThat;
import static org.baeldung.javaxval.enums.demo.CustomerType.DEFAULT;
import static org.baeldung.javaxval.enums.demo.CustomerType.OLD;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.baeldung.javaxval.enums.demo.Customer;
import org.baeldung.javaxval.enums.demo.CustomerUnitTest;
import org.junit.BeforeClass;
import org.junit.Test;
public class EnumNamePatternValidatorUnitTest {
private static Validator validator;
@BeforeClass
public static void setupValidatorInstance() {
validator = Validation.buildDefaultValidatorFactory()
.getValidator();
}
@Test
public void whenEnumMatchesRegex_thenShouldNotReportConstraintViolations() {
Customer customer = new Customer.Builder().withCustomerTypeMatchesPattern(DEFAULT)
.build();
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertThat(violations.isEmpty()).isTrue();
}
@Test
public void whenEnumNull_thenShouldNotReportConstraintViolations() {
Customer customer = new Customer.Builder().withCustomerTypeMatchesPattern(null)
.build();
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertThat(violations.isEmpty()).isTrue();
}
@Test
public void whenEnumDoesNotMatchRegex_thenShouldGiveOccurrenceOfConstraintViolations() {
Customer customer = new Customer.Builder().withCustomerTypeMatchesPattern(OLD)
.build();
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertThat(violations.size()).isEqualTo(1);
assertThat(violations).anyMatch(CustomerUnitTest.havingPropertyPath("customerTypeMatchesPattern")
.and(CustomerUnitTest.havingMessage("must match \"NEW|DEFAULT\"")));
}
}
@@ -0,0 +1,52 @@
package org.baeldung.javaxval.enums;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.baeldung.javaxval.enums.demo.Customer;
import org.baeldung.javaxval.enums.demo.CustomerUnitTest;
import org.junit.BeforeClass;
import org.junit.Test;
public class ValueOfEnumValidatorUnitTest {
private static Validator validator;
@BeforeClass
public static void setupValidatorInstance() {
validator = Validation.buildDefaultValidatorFactory()
.getValidator();
}
@Test
public void whenStringAnyOfEnum_thenShouldNotReportConstraintViolations() {
Customer customer = new Customer.Builder().withCustomerTypeString("DEFAULT")
.build();
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertThat(violations.isEmpty()).isTrue();
}
@Test
public void whenStringNull_thenShouldNotReportConstraintViolations() {
Customer customer = new Customer.Builder().withCustomerTypeString(null)
.build();
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertThat(violations.isEmpty()).isTrue();
}
@Test
public void whenStringNotAnyOfEnum_thenShouldGiveOccurrenceOfConstraintViolations() {
Customer customer = new Customer.Builder().withCustomerTypeString("test")
.build();
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertThat(violations.size()).isEqualTo(1);
assertThat(violations).anyMatch(CustomerUnitTest.havingPropertyPath("customerTypeString")
.and(CustomerUnitTest.havingMessage("must be any of enum class org.baeldung.javaxval.enums.demo.CustomerType")));
}
}
@@ -0,0 +1,66 @@
package org.baeldung.javaxval.enums.demo;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Set;
import java.util.function.Predicate;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.baeldung.javaxval.LocaleAwareUnitTest;
import org.junit.BeforeClass;
import org.junit.Test;
public class CustomerUnitTest extends LocaleAwareUnitTest {
private static Validator validator;
@BeforeClass
public static void setupValidatorInstance() {
validator = Validation.buildDefaultValidatorFactory()
.getValidator();
}
@Test
public void whenAllAcceptable_thenShouldNotGiveConstraintViolations() {
Customer customer = new Customer();
customer.setCustomerTypeOfSubset(CustomerType.NEW);
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertThat(violations).isEmpty();
}
@Test
public void whenAllNull_thenOnlyNotNullShouldGiveConstraintViolations() {
Customer customer = new Customer();
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertThat(violations.size()).isEqualTo(1);
assertThat(violations).anyMatch(havingPropertyPath("customerTypeOfSubset").and(havingMessage("must not be null")));
}
@Test
public void whenAllInvalid_thenViolationsShouldBeReported() {
Customer customer = new Customer();
customer.setCustomerTypeString("invalid");
customer.setCustomerTypeOfSubset(CustomerType.DEFAULT);
customer.setCustomerTypeMatchesPattern(CustomerType.OLD);
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
assertThat(violations.size()).isEqualTo(3);
assertThat(violations).anyMatch(havingPropertyPath("customerTypeString").and(havingMessage("must be any of enum class org.baeldung.javaxval.enums.demo.CustomerType")));
assertThat(violations).anyMatch(havingPropertyPath("customerTypeOfSubset").and(havingMessage("must be any of [NEW, OLD]")));
assertThat(violations).anyMatch(havingPropertyPath("customerTypeMatchesPattern").and(havingMessage("must match \"NEW|DEFAULT\"")));
}
public static Predicate<ConstraintViolation<Customer>> havingMessage(String message) {
return l -> message.equals(l.getMessage());
}
public static Predicate<ConstraintViolation<Customer>> havingPropertyPath(String propertyPath) {
return l -> propertyPath.equals(l.getPropertyPath()
.toString());
}
}
@@ -0,0 +1,67 @@
package org.baeldung.javaxval.javabeanconstraints.test;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.baeldung.javaxval.javabeanconstraints.entities.UserNotBlank;
import org.junit.BeforeClass;
import org.junit.Test;
public class UserNotBlankUnitTest {
private static Validator validator;
@BeforeClass
public static void setupValidatorInstance() {
validator = Validation.buildDefaultValidatorFactory()
.getValidator();
}
@Test
public void whenNotBlankName_thenNoConstraintViolations() {
UserNotBlank user = new UserNotBlank("John");
Set<ConstraintViolation<UserNotBlank>> violations = validator.validate(user);
assertThat(violations.size()).isEqualTo(0);
}
@Test
public void whenBlankName_thenOneConstraintViolation() {
UserNotBlank user = new UserNotBlank(" ");
Set<ConstraintViolation<UserNotBlank>> violations = validator.validate(user);
assertThat(violations.size()).isEqualTo(1);
}
@Test
public void whenEmptyName_thenOneConstraintViolation() {
UserNotBlank user = new UserNotBlank("");
Set<ConstraintViolation<UserNotBlank>> violations = validator.validate(user);
assertThat(violations.size()).isEqualTo(1);
}
@Test
public void whenNullName_thenOneConstraintViolation() {
UserNotBlank user = new UserNotBlank(null);
Set<ConstraintViolation<UserNotBlank>> violations = validator.validate(user);
assertThat(violations.size()).isEqualTo(1);
}
@Test
public void whenToString_thenCorrect() {
UserNotBlank user = new UserNotBlank("John");
assertThat(user.toString()).isEqualTo("User{name=John}");
}
}
@@ -0,0 +1,58 @@
package org.baeldung.javaxval.javabeanconstraints.test;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.baeldung.javaxval.javabeanconstraints.entities.UserNotEmpty;
import org.junit.BeforeClass;
import org.junit.Test;
public class UserNotEmptyUnitTest {
private static Validator validator;
@BeforeClass
public static void setupValidatorInstance() {
validator = Validation.buildDefaultValidatorFactory()
.getValidator();
}
@Test
public void whenNotEmptyName_thenNoConstraintViolations() {
UserNotEmpty user = new UserNotEmpty("John");
Set<ConstraintViolation<UserNotEmpty>> violations = validator.validate(user);
assertThat(violations.size()).isEqualTo(0);
}
@Test
public void whenEmptyName_thenOneConstraintViolation() {
UserNotEmpty user = new UserNotEmpty("");
Set<ConstraintViolation<UserNotEmpty>> violations = validator.validate(user);
assertThat(violations.size()).isEqualTo(1);
}
@Test
public void whenNullName_thenOneConstraintViolation() {
UserNotEmpty user = new UserNotEmpty(null);
Set<ConstraintViolation<UserNotEmpty>> violations = validator.validate(user);
assertThat(violations.size()).isEqualTo(1);
}
@Test
public void whenToString_thenCorrect() {
UserNotEmpty user = new UserNotEmpty("John");
assertThat(user.toString()).isEqualTo("User{name=John}");
}
}
@@ -0,0 +1,58 @@
package org.baeldung.javaxval.javabeanconstraints.test;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.baeldung.javaxval.javabeanconstraints.entities.UserNotNull;
import org.junit.BeforeClass;
import org.junit.Test;
public class UserNotNullUnitTest {
private static Validator validator;
@BeforeClass
public static void setupValidatorInstance() {
validator = Validation.buildDefaultValidatorFactory()
.getValidator();
}
@Test
public void whenNotNullName_thenNoConstraintViolations() {
UserNotNull user = new UserNotNull("John");
Set<ConstraintViolation<UserNotNull>> violations = validator.validate(user);
assertThat(violations.size()).isEqualTo(0);
}
@Test
public void whenNullName_thenOneConstraintViolation() {
UserNotNull user = new UserNotNull(null);
Set<ConstraintViolation<UserNotNull>> violations = validator.validate(user);
assertThat(violations.size()).isEqualTo(1);
}
@Test
public void whenEmptyName_thenNoConstraintViolations() {
UserNotNull user = new UserNotNull("");
Set<ConstraintViolation<UserNotNull>> violations = validator.validate(user);
assertThat(violations.size()).isEqualTo(0);
}
@Test
public void whenToString_thenCorrect() {
UserNotNull user = new UserNotNull("John");
assertThat(user.toString()).isEqualTo("User{name=John}");
}
}
@@ -0,0 +1,98 @@
package org.baeldung.javaxval.methodvalidation;
import java.time.LocalDate;
import java.util.List;
import javax.validation.ConstraintViolationException;
import org.baeldung.javaxval.methodvalidation.model.Customer;
import org.baeldung.javaxval.methodvalidation.model.Reservation;
import org.baeldung.javaxval.methodvalidation.model.ReservationManagement;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { MethodValidationConfig.class }, loader = AnnotationConfigContextLoader.class)
public class ContainerValidationIntegrationTest {
@Autowired
ReservationManagement reservationManagement;
@Rule
public final ExpectedException exception = ExpectedException.none();
@Test
public void whenValidationWithInvalidMethodParameters_thenConstraintViolationException() {
exception.expect(ConstraintViolationException.class);
reservationManagement.createReservation(LocalDate.now(), 0, null);
}
@Test
public void whenValidationWithValidMethodParameters_thenNoException() {
reservationManagement.createReservation(LocalDate.now()
.plusDays(1), 1, new Customer("William", "Smith"));
}
@Test
public void whenCrossParameterValidationWithInvalidParameters_thenConstraintViolationException() {
exception.expect(ConstraintViolationException.class);
reservationManagement.createReservation(LocalDate.now(), LocalDate.now(), null);
}
@Test
public void whenCrossParameterValidationWithValidParameters_thenNoException() {
reservationManagement.createReservation(LocalDate.now()
.plusDays(1),
LocalDate.now()
.plusDays(2),
new Customer("William", "Smith"));
}
@Test
public void whenValidationWithInvalidReturnValue_thenConstraintViolationException() {
exception.expect(ConstraintViolationException.class);
List<Customer> list = reservationManagement.getAllCustomers();
}
@Test
public void whenValidationWithInvalidCascadedValue_thenConstraintViolationException() {
Customer customer = new Customer();
customer.setFirstName("John");
customer.setLastName("Doe");
Reservation reservation = new Reservation(LocalDate.now()
.plusDays(1),
LocalDate.now()
.plusDays(2),
customer, 1);
exception.expect(ConstraintViolationException.class);
reservationManagement.createReservation(reservation);
}
@Test
public void whenValidationWithValidCascadedValue_thenCNoException() {
Customer customer = new Customer();
customer.setFirstName("William");
customer.setLastName("Smith");
Reservation reservation = new Reservation(LocalDate.now()
.plusDays(1),
LocalDate.now()
.plusDays(2),
customer, 1);
reservationManagement.createReservation(reservation);
}
}
@@ -0,0 +1,211 @@
package org.baeldung.javaxval.methodvalidation;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.util.Collections;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.executable.ExecutableValidator;
import org.baeldung.javaxval.methodvalidation.model.Customer;
import org.baeldung.javaxval.methodvalidation.model.Reservation;
import org.baeldung.javaxval.methodvalidation.model.ReservationManagement;
import org.junit.Before;
import org.junit.Test;
public class ValidationIntegrationTest {
private ExecutableValidator executableValidator;
@Before
public void getExecutableValidator() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
this.executableValidator = factory.getValidator()
.forExecutables();
}
@Test
public void whenValidationWithInvalidMethodParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
ReservationManagement object = new ReservationManagement();
Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, int.class, Customer.class);
Object[] parameterValues = { LocalDate.now(), 0, null };
Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues);
assertEquals(3, violations.size());
}
@Test
public void whenValidationWithValidMethodParameters_thenZeroVoilations() throws NoSuchMethodException {
ReservationManagement object = new ReservationManagement();
Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, int.class, Customer.class);
Object[] parameterValues = { LocalDate.now()
.plusDays(1), 1, new Customer("John", "Doe") };
Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues);
assertEquals(0, violations.size());
}
@Test
public void whenCrossParameterValidationWithInvalidParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
ReservationManagement object = new ReservationManagement();
Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, LocalDate.class, Customer.class);
Object[] parameterValues = { LocalDate.now(), LocalDate.now(), new Customer("John", "Doe") };
Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues);
assertEquals(1, violations.size());
}
@Test
public void whenCrossParameterValidationWithValidParameters_thenZeroVoilations() throws NoSuchMethodException {
ReservationManagement object = new ReservationManagement();
Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, LocalDate.class, Customer.class);
Object[] parameterValues = { LocalDate.now()
.plusDays(1),
LocalDate.now()
.plusDays(2),
new Customer("John", "Doe") };
Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues);
assertEquals(0, violations.size());
}
@Test
public void whenValidationWithInvalidConstructorParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
Constructor<Customer> constructor = Customer.class.getConstructor(String.class, String.class);
Object[] parameterValues = { "John", "Doe" };
Set<ConstraintViolation<Customer>> violations = executableValidator.validateConstructorParameters(constructor, parameterValues);
assertEquals(2, violations.size());
}
@Test
public void whenValidationWithValidConstructorParameters_thenZeroVoilations() throws NoSuchMethodException {
Constructor<Customer> constructor = Customer.class.getConstructor(String.class, String.class);
Object[] parameterValues = { "William", "Smith" };
Set<ConstraintViolation<Customer>> violations = executableValidator.validateConstructorParameters(constructor, parameterValues);
assertEquals(0, violations.size());
}
@Test
public void whenCrossParameterValidationWithInvalidConstructorParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
Constructor<Reservation> constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class);
Object[] parameterValues = { LocalDate.now(), LocalDate.now(), new Customer("William", "Smith"), 1 };
Set<ConstraintViolation<Reservation>> violations = executableValidator.validateConstructorParameters(constructor, parameterValues);
assertEquals(1, violations.size());
}
@Test
public void whenCrossParameterValidationWithValidConstructorParameters_thenZeroVoilations() throws NoSuchMethodException {
Constructor<Reservation> constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class);
Object[] parameterValues = { LocalDate.now()
.plusDays(1),
LocalDate.now()
.plusDays(2),
new Customer("William", "Smith"), 1 };
Set<ConstraintViolation<Reservation>> violations = executableValidator.validateConstructorParameters(constructor, parameterValues);
assertEquals(0, violations.size());
}
@Test
public void whenValidationWithInvalidReturnValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
ReservationManagement object = new ReservationManagement();
Method method = ReservationManagement.class.getMethod("getAllCustomers");
Object returnValue = Collections.<Customer> emptyList();
Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateReturnValue(object, method, returnValue);
assertEquals(1, violations.size());
}
@Test
public void whenValidationWithValidReturnValue_thenZeroVoilations() throws NoSuchMethodException {
ReservationManagement object = new ReservationManagement();
Method method = ReservationManagement.class.getMethod("getAllCustomers");
Object returnValue = Collections.singletonList(new Customer("William", "Smith"));
Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateReturnValue(object, method, returnValue);
assertEquals(0, violations.size());
}
@Test
public void whenValidationWithInvalidConstructorReturnValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
Constructor<Reservation> constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class);
Reservation createdObject = new Reservation(LocalDate.now(), LocalDate.now(), new Customer("William", "Smith"), 0);
Set<ConstraintViolation<Reservation>> violations = executableValidator.validateConstructorReturnValue(constructor, createdObject);
assertEquals(1, violations.size());
}
@Test
public void whenValidationWithValidConstructorReturnValue_thenZeroVoilations() throws NoSuchMethodException {
Constructor<Reservation> constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class);
Reservation createdObject = new Reservation(LocalDate.now()
.plusDays(1),
LocalDate.now()
.plusDays(2),
new Customer("William", "Smith"), 1);
Set<ConstraintViolation<Reservation>> violations = executableValidator.validateConstructorReturnValue(constructor, createdObject);
assertEquals(0, violations.size());
}
@Test
public void whenValidationWithInvalidCascadedValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
ReservationManagement object = new ReservationManagement();
Method method = ReservationManagement.class.getMethod("createReservation", Reservation.class);
Customer customer = new Customer();
customer.setFirstName("John");
customer.setLastName("Doe");
Reservation reservation = new Reservation(LocalDate.now()
.plusDays(1),
LocalDate.now()
.plusDays(2),
customer, 1);
Object[] parameterValues = { reservation };
Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues);
assertEquals(2, violations.size());
}
@Test
public void whenValidationWithValidCascadedValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException {
ReservationManagement object = new ReservationManagement();
Method method = ReservationManagement.class.getMethod("createReservation", Reservation.class);
Customer customer = new Customer();
customer.setFirstName("William");
customer.setLastName("Smith");
Reservation reservation = new Reservation(LocalDate.now()
.plusDays(1),
LocalDate.now()
.plusDays(2),
customer, 1);
Object[] parameterValues = { reservation };
Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues);
assertEquals(0, violations.size());
}
}
@@ -0,0 +1,145 @@
package org.baeldung.javaxval.validationgroup;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.baeldung.javaxval.LocaleAwareUnitTest;
import org.junit.BeforeClass;
import org.junit.Test;
public class RegistrationFormUnitTest extends LocaleAwareUnitTest {
private static Validator validator;
@BeforeClass
public static void setupValidatorInstance() {
validator = Validation.buildDefaultValidatorFactory()
.getValidator();
}
@Test
public void whenBasicInfoIsNotComplete_thenShouldGiveConstraintViolationsOnlyForBasicInfo() {
RegistrationForm form = buildRegistrationFormWithBasicInfo();
form.setFirstName("");
Set<ConstraintViolation<RegistrationForm>> violations = validator.validate(form, BasicInfo.class);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> {
assertThat(action.getMessage()).isEqualTo("must not be blank");
assertThat(action.getPropertyPath()
.toString()).isEqualTo("firstName");
});
}
@Test
public void whenAdvanceInfoIsNotComplete_thenShouldGiveConstraintViolationsOnlyForAdvanceInfo() {
RegistrationForm form = buildRegistrationFormWithAdvanceInfo();
form.setZipCode("");
Set<ConstraintViolation<RegistrationForm>> violations = validator.validate(form, AdvanceInfo.class);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> {
assertThat(action.getMessage()).isEqualTo("must not be blank");
assertThat(action.getPropertyPath()
.toString()).isEqualTo("zipCode");
});
}
@Test
public void whenCaptchaIsBlank_thenShouldGiveConstraintViolationsForBasicInfo() {
RegistrationForm form = buildRegistrationFormWithBasicInfo();
form.setCaptcha("");
Set<ConstraintViolation<RegistrationForm>> violations = validator.validate(form, BasicInfo.class);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> {
assertThat(action.getMessage()).isEqualTo("must not be blank");
assertThat(action.getPropertyPath()
.toString()).isEqualTo("captcha");
});
}
@Test
public void whenCaptchaIsBlank_thenShouldGiveConstraintViolationsForAdvanceInfo() {
RegistrationForm form = buildRegistrationFormWithAdvanceInfo();
form.setCaptcha("");
Set<ConstraintViolation<RegistrationForm>> violations = validator.validate(form, AdvanceInfo.class);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> {
assertThat(action.getMessage()).isEqualTo("must not be blank");
assertThat(action.getPropertyPath()
.toString()).isEqualTo("captcha");
});
}
@Test
public void whenBasicInfoIsNotComplete_thenShouldGiveConstraintViolationsForBasicInfoOnly() {
RegistrationForm form = buildRegistrationFormWithBasicInfo();
form.setFirstName("");
Set<ConstraintViolation<RegistrationForm>> violations = validator.validate(form, CompleteInfo.class);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> {
assertThat(action.getMessage()).isEqualTo("must not be blank");
assertThat(action.getPropertyPath()
.toString()).isEqualTo("firstName");
});
}
@Test
public void whenBasicInfoIsCompleteAndAdvanceInfoIsNotComplete_thenShouldGiveConstraintViolationsForAdvanceInfo() {
RegistrationForm form = buildRegistrationFormWithBasicAndAdvanceInfo();
form.setZipCode("");
Set<ConstraintViolation<RegistrationForm>> violations = validator.validate(form, CompleteInfo.class);
assertThat(violations.size()).isEqualTo(1);
violations.forEach(action -> {
assertThat(action.getMessage()).isEqualTo("must not be blank");
assertThat(action.getPropertyPath()
.toString()).isEqualTo("zipCode");
});
}
@Test
public void whenBasicAndAdvanceInfoIsComplete_thenShouldNotGiveConstraintViolationsWithCompleteInfoValidationGroup() {
RegistrationForm form = buildRegistrationFormWithBasicAndAdvanceInfo();
Set<ConstraintViolation<RegistrationForm>> violations = validator.validate(form, CompleteInfo.class);
assertThat(violations.size()).isEqualTo(0);
}
@Test
public void whenBasicAndAdvanceInfoIsComplete_thenShouldNotGiveConstraintViolations() {
RegistrationForm form = buildRegistrationFormWithBasicAndAdvanceInfo();
Set<ConstraintViolation<RegistrationForm>> violations = validator.validate(form);
assertThat(violations.size()).isEqualTo(0);
}
private RegistrationForm buildRegistrationFormWithBasicInfo() {
RegistrationForm form = new RegistrationForm();
form.setFirstName("devender");
form.setLastName("kumar");
form.setEmail("anyemail@yopmail.com");
form.setPhone("12345");
form.setCaptcha("Y2HAhU5T");
return form;
}
private RegistrationForm buildRegistrationFormWithAdvanceInfo() {
RegistrationForm form = new RegistrationForm();
return populateAdvanceInfo(form);
}
private RegistrationForm populateAdvanceInfo(RegistrationForm form) {
form.setCity("Berlin");
form.setCountry("DE");
form.setStreet("alexa str.");
form.setZipCode("19923");
form.setHouseNumber("2a");
form.setCaptcha("Y2HAhU5T");
return form;
}
private RegistrationForm buildRegistrationFormWithBasicAndAdvanceInfo() {
RegistrationForm form = buildRegistrationFormWithBasicInfo();
return populateAdvanceInfo(form);
}
}