[JAVA] Create your own validator with Bean Validation

Overview

A memo of the procedure from writing a self-made validator with Bean Validation to writing a unit test.

Try

I will try to make a validator to judge whether it is a Michael Jackson song name.

Validator class implementation

package com.example.customvalidate;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.ArrayList;
import java.util.List;

public class MJValidator implements ConstraintValidator<MJ, String> {

    private final static List<String> songs = new ArrayList<String>() {
        {
            add("Remember The Time"); add("Stranger In Moscow"); add("You Are Not Alone");
        }
    };

    public void initialize(MJ constraintAnnotation) {
    }

    public boolean isValid(String value, ConstraintValidatorContext context) {
        return songs.stream().anyMatch(song -> song.equals(value));
    }
}

Commentary

--Inherit the ConstraintValidator interface. For the generics, specify the annotation to be created later and the type to be validated. --ʻIsValid` method is used to judge the actual validation. Makes an arbitrary judgment and returns boolean. --In this example, "Remember The Time", "Stranger In Moscow", or "You Are Not Alone" will pass the validation.

Annotation implementation

Make an annotation. Now you can use it like @ MJ

package com.example.customvalidate;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Documented
@Constraint(validatedBy = {MJValidator.class})
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MJ {

    String message() default "you must specify one of Michael Jackson's songs.";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Target({ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @interface List {
        MJ[] value();
    }
}

Commentary

--Specify the class to actually validate in place of @Constraint (validatedBy =). Specify the MJ Validator created above. --For @Target, specify the target to which this annotation can be added. This time, I used arguments and fields. --For message, specify the message to be set in the exception object when validation is caught.

Write a test

package com.example.customvalidate;

import org.junit.Before;
import org.junit.Test;
import javax.validation.*;
import java.util.Set;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

public class MJValidatorTest {

    private Validator validator;

    @Before
    public void setUp() {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    @Test
public void An error will occur if you pass an incorrect song title.() {
        TestBean bean = new TestBean("Remember a Time");
        Set<ConstraintViolation<Object>> violations = validator.validate(bean);
        assertThat(violations.isEmpty(), is(false));
        String expectedMessage = "you must specify one of Michael Jackson's songs.";
        violations.forEach(v -> assertThat(v.getMessage().equals(expectedMessage), is(true)));
    }

    @Test
public void Do not cause an error when passing the correct song title() {
        TestBean bean = new TestBean("Remember The Time");
        Set<ConstraintViolation<Object>> violations = validator.validate(bean);
        assertThat(violations.isEmpty(), is(true));
    }

    private static class TestBean {
        @MJ
        private String song;

        TestBean(String song) {
            this.song = song;
        }
    }
}

Run it and if the test passes ok.

Commentary

--Create an appropriate class as the inner class of the test class and set the annotation created this time in the field. --Running validation for an instance of that class

Recommended Posts

Create your own validator with Bean Validation
Create your own Utility with Thymeleaf with Spring Boot
Create your own Java annotations
Make your own sampler with JMeter
Create your own Solr Function Query
Add Bean Validation with Micronaut (Java)
Easy input check with Bean Validation!
Create your own encode for String.getBytes ()
How to create your own Controller corresponding to / error with Spring Boot
Utilization of Talend component (5) Create your own component
Create your own Android app for Java learning
Add your own authentication items with Spring Security
[Java] Sort ArrayList with elements of your own class
Call your own class created under lib with Rails
Call your own method with PreAuthorize in Spring Security
Try create with Trailblazer
JSON validation with JSON schema
Make your own pomodoro
Self-made Validation with Spring
Create a simple CRUD with SpringBoot + JPA + Thymeleaf ③ ~ Add Validation ~
Register your own Docker image with ECR using AWS CLI
(PC operation at home) Collecting events with your own batch
Java: Start WAS with Docker and deploy your own application
Use your own classes in the lib directory with Rails6