“This is the first day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

Through the custom annotation to realize the parameter value enumeration range verification, applicable to the scene is when an int, String value is in the range of an enumeration, through the Spring MVC parameter verification expansion to achieve the standard parameter verification, to ensure the effectiveness of the user input parameters. To reduce if… The else logic.

Custom annotations

Rely on the import

We introduced the Spring MVC dependency in our pop.xml file and used the Spring Boot Starter for convenience.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
   <version>2.06..RELEASE</version>
</dependency>
Copy the code

Annotations to define

Mssage () is the default error message, like @notnull and so on, indicating a message. Value () is an enumeration range, that is, an enumeration range defined by the parameter field. It is important to note, however, that our enumeration defines only the value field property and the getValue method.

/** * Enumeration value qualification validation * Note: Enumeration must contain the value field **@author zhengsh
 * @dateThe 2021-12-08 * /
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {EnumValueValidator.class})
public @interface EnumValue {
    
    // Default error message
    String message(a) default "the integer is not one of the enum values";

    // The group to which the constraint annotations belong at validation timeClass<? >[] groups()default {};

    // Constrain the annotation's payload
    Class<? extends Payload>[] payload() default {};

    Class<? extends Enum> value();

    // Use when more than one parameter is specified
    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @interfaceList { EnumValue[] value(); }}Copy the code

Defining validators

Explain ConstraintValidator, ConstraintValidator, ConstraintValidator The Spring MVC framework will call the Initialize method to initialize the extension of the current annotation, and during the validation process will call isValid and return true if it passes, false if it doesn’t. If not, an exception will be thrown, and the error message of the exception will contain the message we defined earlier.

/** * Validators associated with constraint annotations **@author zhengsh
 * @dateThe 2021-12-08 * /
public class EnumValueValidator implements ConstraintValidator<EnumValue.Object> {

    private Class<? extends Enum> enumClass;
    private static final String METHOD_NAME = "getValue";

    /** * This method does some initialization verification **@param constraintAnnotation
     */
    public void initialize(EnumValue constraintAnnotation) {
        enumClass = constraintAnnotation.value();
        try {
            // Check whether the enum implements the getValue method
            enumClass.getDeclaredMethod(METHOD_NAME);
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("the enum class has not getValue method", e); }}/** * This method writes the specific verification logic: whether the verification number is in the range of the specified enumeration type **@param value
     * @param constraintValidatorContext
     * @return* /
    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
        // If null returns true, use @notnull or other special annotations
        if (Objects.isNull(value)) {
            return true;
        }
        try {
            Enum[] enumConstants = enumClass.getEnumConstants();
            if (enumConstants == null) {
                // Return enumConstants = null if it is not an enumeration type
                return true;
            }
            for (Enum e : enumClass.getEnumConstants()) {
                Method declaredMethod = e.getClass().getDeclaredMethod(METHOD_NAME);
                Object obj = declaredMethod.invoke(e);
                if (Objects.equals(obj, value)) {
                    return true; }}}catch (Exception e) {
            e.printStackTrace();
        }
        return false; }}Copy the code

Use the sample

Add the @value annotation to the object accepted by the input parameter. 3. Add the Validated mark to the controller’s request parameter method. Let’s look at the code and implementation.

Define the enumeration

First let’s define a Gender enumeration

public enum Gender {
    male(0),
    female(1);

    private int value;

    Gender(int value) {
        this.value = value;
    }

    public int getValue(a) {
        return this.value; }}Copy the code

Use and dependency

Then we can add a custom annotation to our input parameter:

public class Person {
  @enumValue (value = Gender. Class, message = "Gender field is not supported by enumeration ")
  Gender gender;
}
Copy the code

Finally, add @Validated to the Controler method to verify the current parameter.

@RestController
public class PersonController {

    @RequestMapping("/test")
    public String test(@Validated Person person) {
        return "OK"; }}Copy the code

Used to summarize

In Java programming, annotations are a way to simplify code. For example, we use @EnumValue(Gender. Class) annotations to reduce the judgment of parameters. In addition, EnumValueValidator can be used for unified processing to facilitate future expansion. And can be standardized to do some of the basic work of development, so that our business developers more focused on business development.

In the validation – API is also provides a lot of parameters calibration enumerated such as: @ NotNull, @ Min, @ Email annotations in Jakarta. The validation. The constraints bag down to everyone can use.

The resources

  • spring.io