[JAVA-16218] Split javaxval module
This commit is contained in:
6
javaxval-2/.gitignore
vendored
Normal file
6
javaxval-2/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
target/
|
||||
bin/
|
||||
|
||||
10
javaxval-2/README.md
Normal file
10
javaxval-2/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## Java Bean Validation Examples
|
||||
|
||||
This module contains articles about Bean Validation.
|
||||
|
||||
### Relevant Articles:
|
||||
- [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)
|
||||
- [Guide to ParameterMessageInterpolator](https://www.baeldung.com/hibernate-parametermessageinterpolator)
|
||||
- [Hibernate Validator Annotation Processor in Depth](https://www.baeldung.com/hibernate-validator-annotation-processor)
|
||||
- More articles: [[<-- prev]](../javaxval)
|
||||
71
javaxval-2/pom.xml
Normal file
71
javaxval-2/pom.xml
Normal file
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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-2</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<name>javaxval-2</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</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>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- uncomment in order to enable Hibernate Validator Anotation Processor -->
|
||||
<!-- <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> -->
|
||||
<!--<version>${maven.compiler.version}</version> <configuration> <source>${maven.compiler.source}</source> -->
|
||||
<!--<target>${maven.compiler.target}</target> <fork>true</fork> <compilerArgs> <arg>-Averbose=true</arg> -->
|
||||
<!--<arg>-AmethodConstraintsSupported=true</arg> <arg>-AdiagnosticKind=ERROR</arg> </compilerArgs> -->
|
||||
<!--<annotationProcessorPaths> -->
|
||||
<!--<path> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator-annotation-processor</artifactId> -->
|
||||
<!--<version>${hibernate-validator.ap.version}</version> </path> </annotationProcessorPaths> </configuration> -->
|
||||
<!--</plugin> </plugins> </build> -->
|
||||
|
||||
<properties>
|
||||
<hibernate-validator.version>6.2.3.Final</hibernate-validator.version>
|
||||
<hibernate-validator.ap.version>6.2.0.Final</hibernate-validator.ap.version>
|
||||
<maven.compiler.version>3.6.1</maven.compiler.version>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<javax.el.version>3.0.0</javax.el.version>
|
||||
<org.springframework.version>5.3.21</org.springframework.version>
|
||||
<spring.boot.version>2.7.1</spring.boot.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.baeldung.javaxval.hibernate.validator.ap;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Past;
|
||||
|
||||
public class Message {
|
||||
|
||||
@NotNull(message = "Content cannot be null")
|
||||
private String content;
|
||||
|
||||
private boolean isDelivered;
|
||||
|
||||
private List<@NotBlank String> recipients;
|
||||
|
||||
// uncomment in order to trigger AP annotation detection
|
||||
// The annotation @Past is disallowed for this data type.
|
||||
// @Past
|
||||
private String createdAt;
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public Message(String content, boolean isDelivered, List<@NotBlank String> recipients, String createdAt) {
|
||||
this.content = content;
|
||||
this.isDelivered = isDelivered;
|
||||
this.recipients = recipients;
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
// uncomment in order to trigger AP annotation detection
|
||||
// The annotation @Min is disallowed for the return type of this method.
|
||||
// @Min(3)
|
||||
public boolean broadcast() {
|
||||
// setup a logic
|
||||
// to send to recipients
|
||||
return true;
|
||||
}
|
||||
|
||||
// uncomment in order to trigger AP annotation detection
|
||||
// Void methods may not be annotated with constraint annotations.
|
||||
// @NotNull
|
||||
public void archive() {
|
||||
// archive the message
|
||||
}
|
||||
|
||||
// uncomment in order to trigger AP annotation detection
|
||||
// Constraint annotations must not be specified at methods, which are no valid JavaBeans getter methods.
|
||||
// NOTE: add <arg>-AmethodConstraintsSupported=false</arg> to compiler args before
|
||||
// @AssertTrue
|
||||
public boolean delete() {
|
||||
// delete the message
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public boolean isDelivered() {
|
||||
return isDelivered;
|
||||
}
|
||||
|
||||
public void setDelivered(boolean delivered) {
|
||||
isDelivered = delivered;
|
||||
}
|
||||
|
||||
public List<String> getRecipients() {
|
||||
return recipients;
|
||||
}
|
||||
|
||||
public void setRecipients(List<String> recipients) {
|
||||
this.recipients = recipients;
|
||||
}
|
||||
|
||||
public void setCreatedAt(String createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setName(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public Optional<@Past String> getCreatedAt() {
|
||||
return Optional.ofNullable(createdAt);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.baeldung.javaxval.messageinterpolator;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
public class Person {
|
||||
|
||||
@Size(min = 10, max = 100, message = "Name should be between {min} and {max} characters")
|
||||
private String name;
|
||||
|
||||
@Min(value = 18, message = "Age should not be less than {value}")
|
||||
private int age;
|
||||
|
||||
@Email(message = "Email address should be in a correct format: ${validatedValue}")
|
||||
private String email;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.baeldung.javaxval.methodvalidation;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
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;
|
||||
|
||||
import com.baeldung.javaxval.methodvalidation.model.Customer;
|
||||
import com.baeldung.javaxval.methodvalidation.model.Reservation;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan({ "com.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 com.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 com.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 com.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 com.baeldung.javaxval.methodvalidation.constraints;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
import com.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 com.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,66 @@
|
||||
package com.baeldung.javaxval.methodvalidation.model;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Positive;
|
||||
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import com.baeldung.javaxval.methodvalidation.constraints.ConsistentDateParameters;
|
||||
import com.baeldung.javaxval.methodvalidation.constraints.ValidReservation;
|
||||
|
||||
@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,54 @@
|
||||
package com.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.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import com.baeldung.javaxval.methodvalidation.constraints.ConsistentDateParameters;
|
||||
|
||||
@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,22 @@
|
||||
package com.baeldung.javaxval.notnull;
|
||||
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import javax.validation.ValidatorFactory;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class NotNullMethodParameter {
|
||||
|
||||
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
||||
Validator validator = factory.getValidator();
|
||||
|
||||
public int doesNotValidateNotNull(@NotNull String myString) {
|
||||
return myString.length();
|
||||
}
|
||||
|
||||
public int validateNotNull(@NotNull String myString) {
|
||||
validator.validate(myString);
|
||||
return myString.length();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.javaxval.notnull;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@Component
|
||||
@Validated
|
||||
public class ValidatingComponent {
|
||||
|
||||
public int validateNotNull(@NotNull String data)
|
||||
{
|
||||
return data.length();
|
||||
}
|
||||
|
||||
public int callAnnotatedMethod(String data) {
|
||||
return validateNotNull(data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.baeldung.javaxval.messageinterpolator;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import javax.validation.ValidatorFactory;
|
||||
|
||||
import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ParameterMessageInterpolaterIntegrationTest {
|
||||
|
||||
private static Validator validator;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ValidatorFactory validatorFactory = Validation.byDefaultProvider()
|
||||
.configure()
|
||||
.messageInterpolator(new ParameterMessageInterpolator())
|
||||
.buildValidatorFactory();
|
||||
|
||||
validator = validatorFactory.getValidator();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNameLengthLessThanMin_whenValidate_thenValidationFails() {
|
||||
Person person = new Person();
|
||||
person.setName("John Doe");
|
||||
person.setAge(18);
|
||||
|
||||
Set<ConstraintViolation<Person>> violations = validator.validate(person);
|
||||
assertEquals(1, violations.size());
|
||||
|
||||
ConstraintViolation<Person> violation = violations.iterator().next();
|
||||
assertEquals("Name should be between 10 and 100 characters", violation.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAgeIsLessThanMin_whenValidate_thenValidationFails() {
|
||||
Person person = new Person();
|
||||
person.setName("John Stephaner Doe");
|
||||
person.setAge(16);
|
||||
|
||||
Set<ConstraintViolation<Person>> violations = validator.validate(person);
|
||||
assertEquals(1, violations.size());
|
||||
|
||||
ConstraintViolation<Person> violation = violations.iterator().next();
|
||||
assertEquals("Age should not be less than 18", violation.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmailIsMalformed_whenValidate_thenValidationFails() {
|
||||
Person person = new Person();
|
||||
person.setName("John Stephaner Doe");
|
||||
person.setAge(18);
|
||||
person.setEmail("johndoe.dev");
|
||||
|
||||
Set<ConstraintViolation<Person>> violations = validator.validate(person);
|
||||
assertEquals(1, violations.size());
|
||||
|
||||
ConstraintViolation<Person> violation = violations.iterator().next();
|
||||
assertEquals("Email address should be in a correct format: ${validatedValue}", violation.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.baeldung.javaxval.methodvalidation;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
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;
|
||||
|
||||
import com.baeldung.javaxval.methodvalidation.model.Customer;
|
||||
import com.baeldung.javaxval.methodvalidation.model.Reservation;
|
||||
import com.baeldung.javaxval.methodvalidation.model.ReservationManagement;
|
||||
|
||||
@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,212 @@
|
||||
package com.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.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.javaxval.methodvalidation.model.Customer;
|
||||
import com.baeldung.javaxval.methodvalidation.model.Reservation;
|
||||
import com.baeldung.javaxval.methodvalidation.model.ReservationManagement;
|
||||
|
||||
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,21 @@
|
||||
package com.baeldung.javaxval.notnull;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class NotNullMethodParameterUnitTest {
|
||||
|
||||
private NotNullMethodParameter demo = new NotNullMethodParameter();
|
||||
|
||||
@Test
|
||||
public void givenNull_whenInvokedwithNoValidator_thenNullPointerException() {
|
||||
assertThrows(NullPointerException.class, () -> demo.doesNotValidateNotNull(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNull_whenInvokedWithValidator_thenIllegalArgumentException() {
|
||||
assertThrows(IllegalArgumentException.class, () -> demo.validateNotNull(null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.javaxval.notnull;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class ValidatingComponentIntegrationTest {
|
||||
|
||||
@Autowired ValidatingComponent component;
|
||||
|
||||
@Test
|
||||
void givenValue_whenValidate_thenSuccess() {
|
||||
assertThat(component.validateNotNull("Not null!"), is(9));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNull_whenValidate_thenConstraintViolationException() {
|
||||
ConstraintViolationException constraintViolationException = assertThrows(ConstraintViolationException.class, () -> component.validateNotNull(null));
|
||||
Set<ConstraintViolation<?>> constraintViolations = constraintViolationException.getConstraintViolations();
|
||||
assertThat(constraintViolations.iterator().next().getConstraintDescriptor().getAnnotation().annotationType(), is(NotNull.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNull_whenOnlyCalledMethodHasAnnotation_thenNoValidation() {
|
||||
assertThrows(NullPointerException.class, () -> component.callAnnotatedMethod(null));
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
static class TestApplication {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user