From 2f34e89546f439e21714d32e71cca457203bf21a Mon Sep 17 00:00:00 2001 From: lor6 Date: Wed, 12 Apr 2017 14:38:44 +0300 Subject: [PATCH] dynamic validation (#1621) * dynamic validation * small fixes --- .../dynamicvalidation/ContactInfo.java | 26 +++++++++ .../ContactInfoValidator.java | 35 ++++++++++++ .../DynamicValidationApp.java | 15 ++++++ .../config/CustomerController.java | 54 +++++++++++++++++++ .../config/PersistenceConfig.java | 30 +++++++++++ .../dao/ContactInfoExpressionRepository.java | 9 ++++ .../model/ContactInfoExpression.java | 40 ++++++++++++++ .../dynamicvalidation/model/Customer.java | 44 +++++++++++++++ .../src/main/resources/data-expressions.sql | 3 ++ .../src/main/resources/schema-expressions.sql | 5 ++ .../main/resources/templates/customer.html | 41 ++++++++++++++ 11 files changed, 302 insertions(+) create mode 100644 spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java create mode 100644 spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java create mode 100644 spring-boot/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java create mode 100644 spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java create mode 100644 spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java create mode 100644 spring-boot/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java create mode 100644 spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java create mode 100644 spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java create mode 100644 spring-boot/src/main/resources/data-expressions.sql create mode 100644 spring-boot/src/main/resources/schema-expressions.sql create mode 100644 spring-boot/src/main/resources/templates/customer.html diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java new file mode 100644 index 0000000000..41f873b42a --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java @@ -0,0 +1,26 @@ +package com.baeldung.dynamicvalidation; + +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 java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + +@Constraint(validatedBy = { ContactInfoValidator.class }) +@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) +@Retention(RetentionPolicy.RUNTIME) +public @interface ContactInfo { + String message() default "Invalid value"; + + Class[] groups() default {}; + + Class[] payload() default {}; + +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java new file mode 100644 index 0000000000..a8393e2739 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java @@ -0,0 +1,35 @@ +package com.baeldung.dynamicvalidation; + +import java.util.regex.Pattern; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.baeldung.dynamicvalidation.dao.ContactInfoExpressionRepository; +import com.baeldung.dynamicvalidation.model.ContactInfoExpression; + +public class ContactInfoValidator implements ConstraintValidator { + + @Autowired + private ContactInfoExpressionRepository expressionRepository; + + @Override + public void initialize(final ContactInfo contactInfo) { + } + + @Override + public boolean isValid(final String value, final ConstraintValidatorContext context) { + String expressionType = System.getProperty("contactInfoType"); + System.out.println(expressionType); + final ContactInfoExpression expression = expressionRepository.findOne(expressionType); + if (expression != null) { + final String pattern = expression.getPattern(); + if (Pattern.matches(pattern, value)) + return true; + } + return false; + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java new file mode 100644 index 0000000000..361a7b1c03 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java @@ -0,0 +1,15 @@ +package com.baeldung.dynamicvalidation; + +import javax.annotation.security.RolesAllowed; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DynamicValidationApp { + @RolesAllowed("*") + public static void main(String[] args) { + System.setProperty("security.basic.enabled", "false"); + SpringApplication.run(DynamicValidationApp.class, args); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java new file mode 100644 index 0000000000..44db2d5228 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java @@ -0,0 +1,54 @@ +package com.baeldung.dynamicvalidation.config; + +import java.util.List; + +import javax.validation.Valid; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import com.baeldung.dynamicvalidation.dao.ContactInfoExpressionRepository; +import com.baeldung.dynamicvalidation.model.ContactInfoExpression; +import com.baeldung.dynamicvalidation.model.Customer; + +@Controller +public class CustomerController { + + @Autowired + private ContactInfoExpressionRepository expressionRepository; + + @GetMapping("/customer") + public String getCustomerPage(Model model) { + model.addAttribute("contactInfoType", System.getProperty("contactInfoType")); + return "customer"; + } + + @PostMapping("/customer") + public String validateCustomer(@Valid final Customer customer, final BindingResult result, final Model model) { + if (result.hasErrors()) { + model.addAttribute("message", "The information is invalid!"); + } else { + model.addAttribute("message", "The information is valid!"); + } + model.addAttribute("contactInfoType", System.getProperty("contactInfoType")); + return "customer"; + } + + @PostMapping("/updateContactInfoType") + @ResponseBody + public void updateContactInfoType(@RequestParam final String type) { + System.setProperty("contactInfoType", type); + } + + @GetMapping("/contactInfoTypes") + @ResponseBody + public List getContactInfoType(Model model) { + return expressionRepository.findAll(); + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java new file mode 100644 index 0000000000..0eeac2a8dc --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java @@ -0,0 +1,30 @@ +package com.baeldung.dynamicvalidation.config; + +import javax.sql.DataSource; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; + +@EnableJpaRepositories("com.baeldung.dynamicvalidation.dao") +@EntityScan("com.baeldung.dynamicvalidation.model") +@Configuration +public class PersistenceConfig { + + @Bean + public JdbcTemplate getJdbcTemplate() { + return new JdbcTemplate(dataSource()); + } + + @Bean + public DataSource dataSource() { + EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); + EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.H2).addScript("schema-expressions.sql").addScript("data-expressions.sql").build(); + return db; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java new file mode 100644 index 0000000000..ccacc297a5 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.dynamicvalidation.dao; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.baeldung.dynamicvalidation.model.ContactInfoExpression; + +public interface ContactInfoExpressionRepository extends JpaRepository { + +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java new file mode 100644 index 0000000000..9c202b07c8 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java @@ -0,0 +1,40 @@ +package com.baeldung.dynamicvalidation.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class ContactInfoExpression { + + @Id + @Column(name = "expression_type") + private String type; + private String pattern; + + public ContactInfoExpression() { + + } + + public ContactInfoExpression(final String type, final String pattern) { + this.type = type; + this.pattern = pattern; + } + + public String getType() { + return type; + } + + public void setType(final String type) { + this.type = type; + } + + public String getPattern() { + return pattern; + } + + public void setPattern(final String pattern) { + this.pattern = pattern; + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java new file mode 100644 index 0000000000..f043458fce --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java @@ -0,0 +1,44 @@ +package com.baeldung.dynamicvalidation.model; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +import com.baeldung.dynamicvalidation.ContactInfo; + +@Entity +public class Customer { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @ContactInfo + private String contactInfo; + + public Customer() { + } + + public Customer(final long id, final String contactInfo) { + this.id = id; + this.contactInfo = contactInfo; + } + + public String getContactInfo() { + return contactInfo; + } + + public void setContactInfo(final String contactInfo) { + this.contactInfo = contactInfo; + } + + public long getId() { + return id; + } + + public void setId(final long id) { + this.id = id; + } + +} diff --git a/spring-boot/src/main/resources/data-expressions.sql b/spring-boot/src/main/resources/data-expressions.sql new file mode 100644 index 0000000000..3e702a759d --- /dev/null +++ b/spring-boot/src/main/resources/data-expressions.sql @@ -0,0 +1,3 @@ +insert into contact_info_expression values ('email','[a-z0-9!#$%&*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?') +insert into contact_info_expression values ('phone','^([0-9]( |-)?)?(\(?[0-9]{3}\)?|[0-9]{3})( |-)?([0-9]{3}( |-)?[0-9]{4}|[a-zA-Z0-9]{7})$') +insert into contact_info_expression values ('website','^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$') \ No newline at end of file diff --git a/spring-boot/src/main/resources/schema-expressions.sql b/spring-boot/src/main/resources/schema-expressions.sql new file mode 100644 index 0000000000..59f6ab05eb --- /dev/null +++ b/spring-boot/src/main/resources/schema-expressions.sql @@ -0,0 +1,5 @@ +create table contact_info_expression( + expression_type varchar(50) not null, + pattern varchar(500) not null, + PRIMARY KEY ( expression_type ) +); \ No newline at end of file diff --git a/spring-boot/src/main/resources/templates/customer.html b/spring-boot/src/main/resources/templates/customer.html new file mode 100644 index 0000000000..6aec5ab590 --- /dev/null +++ b/spring-boot/src/main/resources/templates/customer.html @@ -0,0 +1,41 @@ + + + +Customer Page + + + + +
+
+Contact Info:
+Contact Info Type:
+ +
+

+
+
+ + \ No newline at end of file