# Building Dynamic Spring Boot Validators

<div><strong>Source</strong>: <a href='https://www.tuanh.net/blog/spring/building-dynamic-spring-boot-validators'>Building Dynamic Spring Boot Validators</a></div><div class="line-post"> 
 <h2 class="title-post">1. Understanding Dynamic Validators</h2> 
</div>
<div class="line-post">
  Dynamic validators are designed to handle validation logic that cannot be predetermined or is subject to change based on various conditions. Unlike static validators which are predefined, dynamic validators adapt their behavior at runtime. 
</div>
<div class="images-post"> 
 <img width="80%" class="element_620700-image" src="https://resource.tuanh.net/article/image/117478ee-bff4-4cd6-ac96-c5c9ee2318d9.png" alt="Image"> 
</div>
<div class="line-post"> 
 <h3 class="sub1">1.1 Why Use Dynamic Validators?</h3> 
</div>
<div class="line-post">
  Dynamic validators offer several benefits: 
</div>
<div class="line-post"> 
 <ul> 
  <li><strong>Flexibility</strong>: They allow validation rules to be altered based on user inputs or external conditions.</li> 
  <li><strong>Reusability</strong>: These validators can be reused across different parts of the application with varying rules.</li> 
  <li><strong>Maintainability</strong>: Changes to validation rules can be made without modifying the core validation logic.</li> 
 </ul> 
</div>
<div class="line-post"> 
 <h3 class="sub1">1.2 Use Cases</h3> 
</div>
<div class="line-post">
  Dynamic validators are useful in scenarios where: 
</div>
<div class="line-post"> 
 <ul> 
  <li>Validation rules are not fixed and may vary based on user roles or configurations.</li> 
  <li>Different entities require similar but slightly different validation logic.</li> 
  <li>Business rules change frequently and need to be reflected immediately without code changes.</li> 
 </ul> 
</div>
<div class="line-post"> 
 <h2 class="title-post">2. Implementing Dynamic Validators in Spring Boot</h2> 
</div>
<div class="line-post">
  To illustrate dynamic validators, we'll use a practical example. Let’s consider an application that requires user data validation, where the validation rules can change based on user roles or other dynamic conditions. 
</div>
<div class="line-post"> 
 <h3 class="sub1">2.1 Setting Up the Project</h3> 
</div>
<div class="line-post">
  First, ensure you have a Spring Boot project set up. Add the necessary dependencies for validation in your pom.xml: 
</div>
<pre class="code">&lt;dependency&gt;<br>    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;<br>    &lt;artifactId&gt;spring-boot-starter-validation&lt;/artifactId&gt;<br>&lt;/dependency&gt;</pre>
<div class="line-post"> 
 <h3 class="sub1">2.2 Creating a Dynamic Validator</h3> 
</div>
<div class="line-post">
  We'll create a custom dynamic validator using Validator interface. Here’s a step-by-step approach: 
</div>
<div class="line-post"> <strong>Define the Validator Interface</strong> 
</div>
<div class="line-post">
  Create an interface for the dynamic validator: 
</div>
<pre class="code"><span class="keyword-css">import</span> javax.validation.ConstraintValidator;<br><span class="keyword-css">import</span> javax.validation.ConstraintValidatorContext;<br><br><span class="keyword-css">public</span> <span class="keyword-css">interface</span> DynamicValidator&lt;T&gt; <span class="keyword-css">extends</span> ConstraintValidator&lt;DynamicConstraint, T&gt; {<br>    <span class="keyword-css">void</span> setValidationCriteria(String criteria);<br>}</pre>
<div class="line-post"> <strong>Implement the Validator</strong> 
</div>
<div class="line-post">
  Implement the DynamicValidator interface. For this example, let’s build a validator that checks if a string contains a specific keyword based on dynamic criteria: 
</div>
<pre class="code"><span class="keyword-css">import</span> javax.validation.ConstraintValidatorContext;<br><br><span class="keyword-css">public</span> <span class="keyword-css">class</span> KeywordValidator <span class="keyword-css">implements</span> DynamicValidator&lt;String&gt; {<br>    <br>    <span class="keyword-css">private</span> String criteria;<br>    <br>    @Override<br>    <span class="keyword-css">public</span> <span class="keyword-css">void</span> initialize(DynamicConstraint constraintAnnotation) {<br>        // No initialization needed<br>    }<br>    <br>    @Override<br>    <span class="keyword-css">public</span> <span class="keyword-css">void</span> setValidationCriteria(String criteria) {<br>        <span class="keyword-css">this</span>.criteria = criteria;<br>    }<br><br>    @Override<br>    <span class="keyword-css">public</span> <span class="keyword-css">boolean</span> isValid(String value, ConstraintValidatorContext context) {<br>        <span class="keyword-css">return</span> value != null &amp;&amp; value.contains(criteria);<br>    }<br>}</pre>
<div class="line-post"> <strong>Create a Custom Annotation</strong> 
</div>
<div class="line-post">
  Create a custom annotation to use the validator: 
</div>
<pre class="code"><span class="keyword-css">import</span> javax.validation.Constraint;<br><span class="keyword-css">import</span> javax.validation.Payload;<br><span class="keyword-css">import</span> java.lang.annotation.ElementType;<br><span class="keyword-css">import</span> java.lang.annotation.Retention;<br><span class="keyword-css">import</span> java.lang.annotation.RetentionPolicy;<br><span class="keyword-css">import</span> java.lang.annotation.Target;<br><br>@Constraint(validatedBy = KeywordValidator.<span class="keyword-css">class</span>)<br>@Target({ ElementType.FIELD, ElementType.METHOD })<br>@Retention(RetentionPolicy.RUNTIME)<br><span class="keyword-css">public</span> @<span class="keyword-css">interface</span> DynamicConstraint {<br>    String message() <span class="keyword-css">default</span> "Invalid value";<br>    Class&lt;?&gt;[] groups() <span class="keyword-css">default</span> {};<br>    Class&lt;? <span class="keyword-css">extends</span> Payload&gt;[] payload() <span class="keyword-css">default</span> {};<br>}</pre>
<div class="line-post"> 
 <h3 class="sub1">2.3 Configuring the Validator at Runtime</h3> 
</div>
<div class="line-post">
  Now, let’s configure the validator to use dynamic criteria: 
</div>
<pre class="code"><span class="keyword-css">import</span> org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;<br><br><span class="keyword-css">import</span> javax.validation.ConstraintValidatorContext;<br><span class="keyword-css">import</span> javax.validation.Validator;<br><span class="keyword-css">import</span> javax.validation.ValidatorFactory;<br><br><span class="keyword-css">public</span> <span class="keyword-css">class</span> ValidatorConfig {<br>    <br>    <span class="keyword-css">private</span> Validator validator;<br><br>    <span class="keyword-css">public</span> ValidatorConfig() {<br>        ValidatorFactory factory = <span class="keyword-css">new</span> LocalValidatorFactoryBean();<br>        <span class="keyword-css">this</span>.validator = factory.getValidator();<br>    }<br>    <br>    <span class="keyword-css">public</span> <span class="keyword-css">void</span> validate(String value, String criteria) {<br>        KeywordValidator keywordValidator = (KeywordValidator) validator.getConstraintsForClass(String.<span class="keyword-css">class</span>)<br>                .getConstraintValidators().iterator().next();<br>        keywordValidator.setValidationCriteria(criteria);<br>        <span class="keyword-css">boolean</span> isValid = keywordValidator.isValid(value, null);<br>        System.out.println("Validation result: " + isValid);<br>    }<br>}</pre>
<div class="line-post"> 
 <h2 class="title-post">3. Testing the Dynamic Validator</h2> 
</div>
<div class="line-post">
  To ensure our dynamic validator works as expected, let’s test it with different criteria. 
</div>
<div class="line-post"> 
 <h3 class="sub1">3.1 Example Test Case</h3> 
</div>
<pre class="code"><span class="keyword-css">public</span> <span class="keyword-css">class</span> DynamicValidatorTest {<br>    <br>    <span class="keyword-css">public</span> <span class="keyword-css">static</span> <span class="keyword-css">void</span> main(String[] args) {<br>        ValidatorConfig validatorConfig = <span class="keyword-css">new</span> ValidatorConfig();<br>        <br>        // Test with different criteria<br>        validatorConfig.validate("Hello World", "World");  // Expected output: true<br>        validatorConfig.validate("Hello World", "Java");   // Expected output: false<br>    }<br>}</pre>
<div class="line-post"> 
 <h2 class="title-post">4. Conclusion</h2> 
</div>
<div class="line-post">
  Dynamic validators offer a flexible approach to validation, enabling your Spring Boot application to adapt to changing requirements effortlessly. By implementing dynamic validators, you can ensure that your application remains robust and maintainable even as validation needs evolve. 
</div>
<div class="line-post">
  Feel free to ask any questions or share your thoughts in the comments below! 
</div><p><strong>Read more at </strong>: <a href='https://www.tuanh.net/blog/spring/building-dynamic-spring-boot-validators'>Building Dynamic Spring Boot Validators</a></p>
