Springboot中使用自定义validator

Springboot动态装载卸载Bean

springboot的validation(转) 

springboot数据格式验证(二)——自定义日期格式验证

springboot数据格式验证(一)

在springboot中自定义了一个校验注解

@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = UniqueProcessInfoValidator.class)

public @interface UniqueProcessInfo {
    String message() default "jobName在当前项目中已存在!";

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

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

下面是指定的校验逻辑类

//研究发现hibernate验证器拿不到spring bean, processInfoService总是null!!!
@Service
public class UniqueProcessInfoValidator implements ConstraintValidator<UniqueProcessInfo, ProcessInfo> {
    @Autowired
    private ProcessInfoService processInfoService;

    @Override
    public boolean isValid(ProcessInfo processInfo, ConstraintValidatorContext constraintValidatorContext) {

        boolean exists = processInfoService.existsDuplicateProcess(processInfo);

        return !exists;
    }
}

经研究发现validator是hibernate维护的,所以在启动的时候拿不到spring中的Bean。

不得已需要用到spring动态装载bean的方式。

改写成下面这种写法

@Slf4j
public class UniqueProcessInfoValidator implements ConstraintValidator<UniqueProcessInfo, ProcessInfo> {


    @Override
    public boolean isValid(ProcessInfo processInfo, ConstraintValidatorContext constraintValidatorContext) {
        ProcessInfoService processInfoService = SpringContextUtil.getBean(ProcessInfoService.class);
        boolean exists = processInfoService.existsDuplicateProcess(processInfo);
        log.info(String.valueOf(exists));
        return !exists;
    }
}

然后就可以了!

附录:

验证经验

1.把校验行为从分层中剥离出来,不是在哪一层做,而是在 Bean 上做。

2.要对校验项预置好默认的提示信息,这样当校验不通过时,用户能获得明确的修正提示

3.要把不带业务含义的格式校验注解放到 Bean 的类定义之上,把带业务逻辑的校验放到 Bean 的类定义的外面,

原因是放在类定义中的注解能够自动运行,而放到类外面的业务校验需要像前面的示例代码那样,明确标出注解时才会运行,带业务逻辑的校验,通常就需要外部资源参与执行,这不仅仅是多消耗一点时间和运算资源的问题,因为我们很难保证依赖的每个服务都是幂等的,重复执行校验很可能会带来额外的副作用。因此应该放到外面,让使用者自行判断是否要触发

4.对应校验对象不是bean的情况,请参考下面博文,将校验加在函数参数上

springboot的validation(转) 

posted @ 2022-08-01 09:35  Mars.wang  阅读(1080)  评论(0编辑  收藏  举报