SpringBoot-表单验证-统一异常处理-自定义验证信息源( 四 )

< USERS.size(); i++) {if(USERS.get(i).getId().equals(id)) {USERS.set(i,sysUser);}}return CommonResult.success("更新成功");}/*** 根据Id删除用户信息* @param id 主键* @return 成功标识*/@DeleteMapping("{id}")public CommonResult deleteById(@PathVariable Long id) {USERS.removeIf(obj -> obj.getId().equals(id));return CommonResult.success("删除成功");}/*** 获取表单验证错误msg* @param fieldError 报错字段* @return msg*/public String getErrorMsg(FieldError fieldError) {String field = fieldError.getField();Object rejectedValue = fieldError.getRejectedValue();String msg = "[" + fieldError.getDefaultMessage() + "]";log.error("{}:字段=={}t值=={}", msg, field, rejectedValue);return msg;}}3.4 启动测试查询:
输入不合法手机号

SpringBoot-表单验证-统一异常处理-自定义验证信息源

文章插图
 
新增:
正常情况
SpringBoot-表单验证-统一异常处理-自定义验证信息源

文章插图
 
? 去掉邮箱
SpringBoot-表单验证-统一异常处理-自定义验证信息源

文章插图
 
修改:
? 去掉id
SpringBoot-表单验证-统一异常处理-自定义验证信息源

文章插图
 
删除:
SpringBoot-表单验证-统一异常处理-自定义验证信息源

文章插图
 
4. 自定义验证很多时候框架提供的功能并不能满足我们的业务场景,这时我们需要自定义一些验证规则来完成验证 。
4.1 添加注解import com.ldx.valid.validation.PhoneValidator;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.ElementType.TYPE_USE;import static java.lang.annotation.RetentionPolicy.RUNTIME;/** * 验证手机号是否合法 * @author ludangxin * @date 2021/8/7 */@Documented@Constraint(validatedBy = {PhoneValidator.class})@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention(RUNTIME)public @interface Phone {//默认错误消息String message() default "不是一个合法的手机号";//分组Class<?>[] groups() default {};//载荷 将某些元数据信息与给定的注解声明相关联的方法Class<? extends Payload>[] payload() default {};//指定多个时使用@Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})@Retention(RUNTIME)@Documented@interface List {Phone[] value();}}4.2 编写验证逻辑import javax.validation.ConstraintValidator;import com.ldx.valid.annotation.Phone;import javax.validation.ConstraintValidatorContext;import java.util.Objects;import java.util.regex.Pattern;/** * 手机号校验器 * @author ludangxin * @date 2021/8/7 */public class PhoneValidator implements ConstraintValidator<Phone, String> {/*** 手机号正则表达式*/private static final String REGEXP_PHONE = "^1[3456789]\d{9}$";@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {if(Objects.isNull(value)) {return true;}return Pattern.matches(REGEXP_PHONE, value);}}4.3 修改实体给SysUser.phone 属性添加注解@Phone
@Phone(groups = {ValidationInterface.update.class,ValidationInterface.add.class,ValidationInterface.select.class})@NotEmpty(message = "手机号不能为空", groups = {ValidationInterface.add.class})private String phone;4.4 启动测试输入错误的手机号进行测试
SpringBoot-表单验证-统一异常处理-自定义验证信息源

文章插图
 
4.5 @Pattern当然validation也提供了基于正则匹配的注解@Pattern
【SpringBoot-表单验证-统一异常处理-自定义验证信息源】@Pattern(message = "手机号不合法", regexp = "^1[3456789]\d{9}$", groups = {ValidationInterface.add.class})@NotEmpty(message = "手机号不能为空", groups = {ValidationInterface.add.class})private String phone;
注意是javax.validation.constraints包下的
测试
SpringBoot-表单验证-统一异常处理-自定义验证信息源

文章插图
 
5. 调用过程验证有的时候我们在参数传输过程中需要对传入的对象做参数验证,但是上面介绍的都是对参数绑定时的验证,那能不能使用validation进行验证呢?
答案肯定是可以的 。
5.1 使用 spring bean5.1.1 注入validatorbean validator 是我们在config文件中定义的bean,如果使用了springboot默认的配置ValidationAutoConfiguration::defaultValidator(),直接注入bean name defaultValidator即可
@Resource(name = "validator")javax.validation.Validator validator;5.1.2 定义验证方法public void validateParams(SysUser user) {validator.validate(user, ValidationInterface.add.class).stream().findFirst().ifPresent(obj -> {String objName = obj.getRootBean().getClass().getSimpleName();String fieldName = obj.getPropertyPath().toString();Object val = obj.getInvalidValue();String msg = obj.getMessage();String errMsg = MessageFormat.format(msg + ":对象:{0},字段:{1},值:{2}", objName, fieldName, val);throw new RuntimeException(errMsg);});


推荐阅读