Springboot mini - Solon details - use, customization and extension of Solon's verification framework

Springboot min -Solon explain series:
Springboot mini - Solon details (I) - quick start
Springboot mini - Solon details (II) - the core of Solon
Springboot mini - Solon details (III) - Solon's web Development
Springboot mini - Solon details (IV) - Solon's transaction propagation mechanism
Springboot mini - Solon explanation (V) - Solon Plugin of Solon extension mechanism

In the process of business implementation, especially the development of external interface, we need to verify the request and return the error status code and description. lombok framework has many wonderful annotations, but others throw an exception, which may not match some requirements.

This article will introduce the extended verification framework of spring min Solon: Solon extend. The use and extension of validation (org. Noear: Solo web has been included). The effect is as follows:

@Valid
@Controller
public class UserController {
    @NoRepeatSubmit  //Repeat submission verification
    @Whitelist     //White list verification
    @NotNull({"name", "mobile", "icon", "code"})  //Non NULL validation
    @Numeric({"code"})
    @Mapping("/user/add")
    public void addUser(String name, @Pattern("^http") String icon, int code, @Pattern("^13\\d{9}$") String mobile){
        //...
    }
}

Compared with Spring, the Validator is competing for Bean, while Solon is competing for Context (i.e. http parameter). This is very different. Solon's design is to verify the http parameters before the Action is executed.

annotation Scope of action explain
Date parameter The parameter value of the verification annotation is in date format
DecimalMax(value) parameter The parameter value of the verification annotation is less than or equal to the value specified by @ DecimalMax
DecimalMin(value) parameter The parameter value of the verification annotation is greater than or equal to the value specified by @ DecimalMin
Email parameter The parameter value of the verification annotation is in e-mail format
Length(min, max) parameter The parameter value length of the verification annotation is within the range of min and max
Max(value) parameter The parameter value of the verification annotation is less than or equal to the value specified by @ Max
Min(value) parameter The parameter value of the verification annotation is greater than or equal to the value specified by @ Min
NoRepeatSubmit Controller or action Verify that the request is not repeated
NotBlank Action or parameter The parameter value of the verification annotation is not blank
NotEmpty Action or parameter The parameter value of the verification annotation is not empty
NotNull Action or parameter The parameter value of the validation annotation is not null
NotZero Action or parameter The parameter value of the verification annotation is not 0
Null Action or parameter The parameter value of the validation annotation is null
Numeric Action or parameter The parameter value of the verification annotation is in digital format
Pattern(value) parameter Verify that the parameter value of the annotation matches the specified regular expression
Whitelist Controller or action Verify that this request is within the white list
Valid Controller or action Enable verification capability for controller or action

The annotation that can be applied to [action or parameter] can support the verification of multiple parameters when added to the action.

1, Custom use

solon.extend.validation provides a set of customization and extension interfaces through validator manager.

1. @ NoRepeatSubmit changed to distributed lock

NoRepeatSubmit uses the local delay lock by default. If a distributed lock is needed, customize it for the distributed environment:

public class NoRepeatLockNew implements NoRepeatLock {
    @Override
    public boolean tryLock(String key, int seconds) {
        //Using distributed locks
        //
        return LockUtils.tryLock(XWaterAdapter.global().service_name(), key, seconds);
    }
}

ValidatorManager.setNoRepeatLock(new NoRepeatLockNew());

Or completely override the NoRepeatSubmitValidator and re register

2. @ Whitelist implementation verification

At the framework level, there is no way to provide Whitelist with a list library, so it needs to complete the docking through an interface.

public class WhitelistCheckerNew implements WhitelistChecker {
    @Override
    public boolean check(Whitelist anno, Context ctx) {
        String ip = IPUtils.getIP(ctx);

        return WaterClient.Whitelist.existsOfServerIp(ip);
    }
}

ValidatorManager.setWhitelistChecker(new WhitelistCheckerNew());

Or completely rewrite whitelist validator and re register

3. Transformation verification output

solon. extend. The default output of validation is http 400 status + json; Try to remove the http 400 status.

@Configuration
public class Config {
    @Bean  //Solon's @ Bean also supports null functions and provides run declarations for other functions
    public void adapter() {
        ValidatorManager.global().onFailure((ctx, ano, rst, message) -> {
            ctx.setHandled(true);
        
            if (Utils.isEmpty(message)) {
                message = new StringBuilder(100)
                        .append("@")
                        .append(ano.annotationType().getSimpleName())
                        .append(" verification failed")
                        .toString();
            }
        
            ctx.output(message);
        
            return true;
        });
    }
}

2, Add an extension annotation

1. Define a verification annotation @ Date first

Take a slack and throw out your own. As long as you can do it yourself: - P

@Target({ElementType.PARAMETER})   //Let it only act on parameters. No matter where it acts, it is ultimately the verification of Context
@Retention(RetentionPolicy.RUNTIME)
public @interface Date {
    @Note("date expression, The default is: ISO format")  //Note annotation is used so that you can see it when you use it
    String value() default  "";

    String message() default "";
}

2. Add verifier implementation class of @ Date

public class DateValidator implements Validator<Date> {
    public static final DateValidator instance = new DateValidator();


    @Override
    public String message(Date anno) {
        return anno.message();
    }

    @Override
    public Result validate(Context ctx, Date anno, String name, StringBuilder tmp) {
        String val = ctx.param(name);
        if (val == null || tryParse(anno, val) == false) {
            tmp.append(',').append(name);
        }

        if (tmp.length() > 1) {
            return Result.failure(tmp.substring(1));
        } else {
            return Result.succeed();
        }
    }

    private boolean tryParse(Date anno, String val) {
        try {
            if (Utils.isEmpty(anno.value())) {
                DateTimeFormatter.ISO_LOCAL_DATE_TIME.parse(val);
            } else {
                DateTimeFormatter.ofPattern(anno.value()).parse(val);
            }

            return true;
        } catch (Exception ex) {
            return false;
        }
    }
}

3. Register with Validation Manager

@Configuration
public class Config {
    @Bean
    public void adapter() {
        //
        // This is the registration verifier. If some validators are rewritten, they are also registered here
        //
        ValidatorManager.global().register(Date.class, DateValidator.instance);
    }
}

4. Use it

@Valid
@Controller
public class UserController extends VerifyController{
    @Mapping("/user/add")
    public void addUser(String name, @Date("yyyy-MM-dd") String birthday){
        //...
    }
}

Attachment: Solon project address

Tags: Spring Boot solon

Posted by DepretioN on Tue, 03 May 2022 08:42:04 +0300