Write it down while it’s hot and give it to your future self
The foreword 0.
Spring Validation, as a parameter Validation framework, is already very powerful in its own right and can cover most business scenario requirements, such as @notnull, @Notblank, @min, @max, @size, @email, and so on.
For more complex business scenarios, however, Spring Validation’s inherent annotations are not useful. For example, suppose you have an interface where one of the input parameters is of type String, and because of business requirements, the value of the input parameter can only be passed in a allowed list. Return the exception directly.
It is common practice to make a logical judgment on the input parameters in the business code, but this will lead to the coupling of the business code and the verification code, and the development efficiency is not high, and the code is not very beautiful. A more elegant approach would be to customize a validator and enumeration class to fulfill this requirement.
1. The architecture diagram
Module description:
- 1:
DTO
-Take in revenueDTO
Class so that the received parameter becomes an object- 1-1:
private String para
The object with@EnumCheck
Note, indicatepara
Need to be checked - 1-2:
private String para1
Object without@EnumCheck
Note, indicatepara1
It does not need to be checked
- 1-1:
- 2:
EnumCheck
– is an annotation class that needs to implement custom annotations in the class - 3:
EnumUtil
– Enumeration tool class, which passes an enumeration parameter to determine whether the parameter is in the specified enumeration. If it exists, it returns an enumeration. If it does not, it returns an enumerationnull
- 4:
Enum Class
– User-defined enumeration class used to store the scope of the parameters - 5: Exception logic – When
EnumCheck
After the failure, the exception logic is displayed - 6: Follow-up service logic – When
EnumCheck
After the operation succeeds, enter the following service logic
2. Code description
2.1 JenkinsProcessBuildReqDTO.java
Input parameters are received by the DTO class, which defines one or more fields that need to be validated.
@Data
public class JenkinsProcessBuildReqDTO {
/** * Deployment environment */
@enumCheck (message = "Error in environment ", enumClass = JenkinsProcessEnum. Class)
private String environment;
}
Copy the code
2.2 JenkinsProcessEnum.java
User-defined enumerated type, used to deposit into the scope of the, if the enumeration class, limit the JenkinsProcessBuildReqDTO. The scope of the environment in DEPLOY_SIT DEPLOY_UAT, DEPLOY_SIT_UAT these three enumeration.
import lombok.Getter;
@Getter
public enum JenkinsProcessEnum {
/** * Sit environment */
DEPLOY_SIT("0"."SIT"."Sit environment"),
/** * UAT environment */
DEPLOY_UAT("1"."UAT"."Uat environment"),
/** * SIT and UAT environments */
DEPLOY_SIT_UAT("2"."SIT_UAT"."Sit and UAT environments"),;private String code;
private String name;
private String desc;
JenkinsProcessEnum(String code, String name, String desc) {
this.code = code;
this.name = name;
this.desc = desc; }}Copy the code
2.3 EnumUtil.java
This class provides a method, getEnumByParameter, that passes an enumParameter to determine whether the parameter is in the specified enumeration clazz. If yes, return the enumeration corresponding to the enumParameter. If no, return null
@Slf4j
public class EnumUtil {
/ * * * *@author arkMon
* @dateAll 2021/2/23 *@paramThe name of the enumerated class passed in by clazz@paramGetEnumMethodName The method name * passed in to the enumeration class clazz@paramEnumParameter Enumeration parameter *@returnT specific enumeration value or null */
public static <T extends Enum<T>> T getEnumByParameter(Class<T> clazz, String getEnumMethodName, Object enumParameter){
T result = null;
try{
// The value () method is not available on the Enum interface. We can still obtain all instances of the Enum using the Class object
T[] arr = clazz.getEnumConstants();
// Get the method defined
Method targetMethod = clazz.getDeclaredMethod(getEnumMethodName);
if (targetMethod == null) {
log.error("getEnumMethodName=" + getEnumMethodName + "Nonexistent");
return null;
}
Object typeVal;
// Iterate over the enumeration definitions
for(T entity:arr){
if (enumParameter instanceof Integer) {
typeVal = Integer.valueOf(String.valueOf(targetMethod.invoke(entity)));
} else if (enumParameter instanceof String) {
// Get the passed method
typeVal = String.valueOf(targetMethod.invoke(entity)).replace(""."");
// The value of the executed method is equal to the value of the argument passed to judge
enumParameter = ((String) enumParameter).replace(""."");
} else {
log.error("The enumType passed in is not an Integer or a String");
return null;
}
if(typeVal.equals(enumParameter)){
// Return this enumeration
result = entity;
break; }}}catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
returnresult; }}Copy the code
2.4 EnumCheck.java
Custom validator annotations. In the isValid method of the Validator class below this annotation, we implement the logic for the custom validator:
If the code or name in the enumeration is passed in, use the getEnumByParameter method to find the corresponding enumeration. If it is found, return true. If it is not found, return false.
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumCheck.Validator.class)
public @interface EnumCheck {
String message(a) default "{enum.value.invalid}"; // Error message Class
> enumClass(); // Enumeration Class
[] groups() default {}; Class
[] payload() default {}; String enumMethodCode() default "getCode"; String enumMethodName() default"getName"; Boolean allowNull() default false; Class Validator implements ConstraintValidator
{private class
> enumClass; private String enumMethodCode; private String enumMethodName; private boolean allowNull; @Override public void initialize(EnumCheck enumValue) { enumMethodCode = enumValue.enumMethodCode(); enumMethodName = enumValue.enumMethodName(); enumClass = enumValue.enumClass(); allowNull = enumValue.allowNull(); } @Override public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) { if (value == null) { return allowNull; } if (enumClass == null) { return Boolean.TRUE; } JenkinsProcessEnum enumByParameter = EnumUtil.getEnumByParameter(JenkinsProcessEnum.class, enumMethodCode, value); if (enumByParameter ! = null) { return true; } JenkinsProcessEnum enumByParameter1 = EnumUtil.getEnumByParameter(JenkinsProcessEnum.class, enumMethodName, value); if (enumByParameter1 ! = null) { return true; } return false; }}}
,>Copy the code
Ref
-
- Spring Validation is used for data backend validation
-
- Java Bean Validation best practices