[Springboot] validator enumeration value check

Editor:

  https://blog.csdn.net/aiyaya_/article/details/78588200

I. Introduction

In the spring project, check function uses hibernate validator parameter is a good choice, our projects also use it to verify, and save a lot of ugly validation logic, the readability of the code also increased significantly This chapter will take you to use hibernate validator custom annotation functions to achieve a logical enumeration value check.

Second, demand

Let's clear our needs, the program development process, we often have a property value of an object can only appear in the check needs a set of constants, for example: a user can only gender field gender equal MALE / FEMALE two one of the two values, the status of the user account status can only be equal to: NORMAL / DISABLED / DELETED one, etc., then how can we better check this parameter it? We want to have a java annotation, mark it on the field you want to check, when you turn hibernate validator check, you can check its field values ​​are correct.

Third, the implementation

A set of constant values mentioned above, our first reaction would be to define an enumerated class, try not placed under a unified class constants, once the system is up huge, difficult to maintain and constants are looking for, so early so that when the code should also have some regulatory constraints, here we use the convention set a constant value when the enumeration and the enumeration class in the class corresponding to the object's (the above mentioned user function, for example, we should GenerEnum, UserStatusEnum enumeration placed under User.java, easy to find)
where we define a class called EnumValue.java notes, under which there are two main parameters are enumClass for a specified enum class, enumMethod specify the methods to be verified, Here we look at code.

Fourth, code implementation

package com.zhuma.demo.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;

import org.assertj.core.util.Strings;

/**
 * @desc 校验枚举值有效性
 * 
 * @author zhumaer
 * @since 10/17/2017 3:13 PM
 */
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumValue.Validator.class)
public @interface EnumValue {

	String message() default "{custom.value.invalid}";

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

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

	Class<? extends Enum<?>> enumClass();

	String enumMethod();

	class Validator implements ConstraintValidator<EnumValue, Object> {

		private Class<? extends Enum<?>> enumClass;
		private String enumMethod;

		@Override
		public void initialize(EnumValue enumValue) {
			enumMethod = enumValue.enumMethod();
			enumClass = enumValue.enumClass();
		}

		@Override
		public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
			if (value == null) {
				return Boolean.TRUE;
			}

			if (enumClass == null || enumMethod == null) {
				return Boolean.TRUE;
			}

			Class<?> valueClass = value.getClass();

			try {
				Method method = enumClass.getMethod(enumMethod, valueClass);
				if (!Boolean.TYPE.equals(method.getReturnType()) && !Boolean.class.equals(method.getReturnType())) {
					throw new RuntimeException(Strings.formatIfArgs("%s method return is not boolean type in the %s class", enumMethod, enumClass));
				}

				if(!Modifier.isStatic(method.getModifiers())) {
					throw new RuntimeException(Strings.formatIfArgs("%s method is not static method in the %s class", enumMethod, enumClass));
				}
	
				Boolean result = (Boolean)method.invoke(null, value);
				return result == null ? false : result;
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				throw new RuntimeException(e);
			} catch (NoSuchMethodException | SecurityException e) {
				throw new RuntimeException(Strings.formatIfArgs("This %s(%s) method does not exist in the %s", enumMethod, valueClass, enumClass), e);
			}
		}
 
	}
}

Remark

1) need to implement custom annotation ConstraintValidator validation class, where we define a class called Validator to achieve it, while achieving the following two methods that initialize, isValid, a method of initialization parameters, the validation logic is further the method of this example we will check the annotation in the class definition, with @Constraint (validatedBy = EnumValue.Validator.class) annotation specifies the class verification, the internal logic is easy to implement call using static verification method based reflective manner .
2) the method was verified our requirements, it must return a value of type Boolean or boolean, and must be a static method, returns the returned value is null we believe is the checksum does not pass, according to take false logic.

Fifth, use demo

Check audience class

package com.zhuma.demo.model.po;

import java.io.Serializable;
import java.util.Date;

import javax.validation.constraints.Pattern;

import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;

import com.zhuma.demo.annotation.EnumValue;
import com.zhuma.demo.validator.CreateGroup;

/**
 * @desc 用户PO

 * @author zhumaer
 * @since 6/15/2017 2:48 PM
 */
public class User implements Serializable {

	private static final long serialVersionUID = 2594274431751408585L;

	/**
	 * 用户ID
	 */
	private Long id;

	/ ** 
	 * Password 
	 * / 
	@NotBlank 
	Private String pwd; 

	/ ** 
	 * Nickname 
	 * / 
	@NotBlank 
	@Length (= min. 1, max = 64) 
	Private String Nickname; 

	/ ** 
	 * avatar 
	 * / 
	Private String IMG; 

	/ ** 
	 * Tel 
	 * / 
	@Pattern (regexp = "^. 1 [3-9]. 9 \\ {D} $") 
	Private phone String; 

	/ ** 
	 * account status 
	 * / 
	@EnumValue (enumClass = UserStatusEnum.class, enumMethod = "IsValidName") 
	Private Status String; 

	/ ** 
	 * the latest login time 
	 * / 
	Private a date latestLoginTime; 

	/ ** 
	 * Log latest IP 
	 * /
	String latestLoginIp Private; 

	Private createTime a Date; 
	Private updateTime a Date; 
	
	/ ** 
	 * User state enumeration 
	 * / 
	public enum UserStatusEnum { 
		/ ** normal * / 
		the NORMAL, 
		/ disable ** * / 
		DISABLED, 
		/ ** deleted * / 
		DELETED; 

		/ ** 
		 * parameter determines the legitimacy 
		 * / 
		public static Boolean IsValidName (String name) { 
			for (userStatusEnum userStatusEnum: UserStatusEnum.values ()) { 
				IF (. userStatusEnum.name () the equals (name)) { 
					return to true; 
				} 
			} 
			return to false; 
		} 
	} 
	
	// getters omitted, setter method 

}  

controller class

 package com.zhuma.demo.web.user;

import java.util.Date;

import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.zhuma.demo.model.po.User;

/**
 * @desc 用户管理控制器
 * 
 * @author zhumaer
 * @since 6/20/2017 16:37 PM
 */
@RestController
@RequestMapping("/users")
public class UserController {

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public User addUser(@Validated @RequestBody User user) {
    	user.setId(10000L);
    	user.setCreateTime(new Date());
        return user;
    }

}  

Check results

 

 


Finally
Well, annotation features a simple enumeration value check completed.

Guess you like

Origin www.cnblogs.com/wjqhuaxia/p/12153053.html