java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot @Valid @Validated自定义校验

SpringBoot使用@Valid或者@Validated时自定义校验的场景分析

作者:乐韵天城

文章介绍了在Java开发中,如何处理需要根据多个字段进行校验的自定义场景,通过创建自定义注解和实现相应的约束类,可以在DTO类中对这些字段进行复杂校验,最后,通过全局异常处理机制,可以统一处理校验失败的情况,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧

一、自定义校验场景

平常开发项目想要校验参数是否合法一般会在类的字段上添加一些校验注解比如@NotEmpty、@Size、@Pattern等等,但这种是针对单个字段的校验,当我们有一些比较灵活的场景,比如根据多个字段进行判断应该如何做呢。

二、添加自定义注解

场景:假设我们有一个注册接口,有两个字段分别是注册类型(手机注册、邮箱注册)、联系方式,当用户以手机号注册时我们需要校验手机号是否合法,当用户以邮箱注册时我们需要校验邮箱是否合法。

自定义注解

package com.promote.demo.util;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {CustomValidator.class})
public @interface Custom {
    String message() default "";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

自定义注解的约束实现类

package com.promote.demo.util;
import cn.hutool.core.lang.PatternPool;
import com.promote.demo.model.RegisterModel;
import org.apache.commons.lang3.StringUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class CustomValidator implements ConstraintValidator<Custom, RegisterModel> {
    @Override
    public boolean isValid(RegisterModel value, ConstraintValidatorContext context) {
        context.disableDefaultConstraintViolation();
        String type = value.getType();
        int constraints = 0;
        if (StringUtils.isNotBlank(value.getContact())) {
            //是否手机号注册
            if ("1".equals(type) && !PatternPool.MOBILE.matcher(value.getContact()).matches()) {
                context.buildConstraintViolationWithTemplate("手机号格式不正确").addConstraintViolation();
                constraints++;
            }
            //是否邮件注册
            if ("2".equals(type) && !PatternPool.EMAIL.matcher(value.getContact()).matches()) {
                context.buildConstraintViolationWithTemplate("邮箱格式不正确").addConstraintViolation();
                constraints++;
            }
        }
        return constraints <= 0;
    }
}

注册接口的DTO类

package com.promote.demo.model;
import com.promote.demo.util.Custom;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
@Data
@Custom
public class RegisterModel implements Serializable {
    @ApiModelProperty("注册类型")
    @NotBlank(message = "注册类型不能为空")
    private String type;
    @ApiModelProperty("联系方式")
    @NotBlank(message = "联系方式不能为空")
    private String contact;
}

全局异常

package com.promote.demo.controller;
import com.promote.demo.model.BaseResponse;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.stream.Collectors;
@ControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 拦截参数不合法异常,自定义输出结果
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public BaseResponse<String> bindException (Exception ex) {
        BindException bindException = (BindException) ex;
        List<ObjectError> errors = bindException.getAllErrors();
        String msg = errors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(","));
        BaseResponse<String> baseResponse = new BaseResponse<>();
        baseResponse.setMsg(msg);
        baseResponse.setCode(HttpStatus.BAD_REQUEST.value());
        baseResponse.setSuccess(false);
        return baseResponse;
    }
}

三、运行效果

到此这篇关于SpringBoot使用@Valid或者@Validated时自定义校验场景分析的文章就介绍到这了,更多相关SpringBoot @Valid @Validated自定义校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文