Spring data rest中使用Validator和Listener

传统的controller-service-dao模式中,处理业务数据时,可以在service中处理,但是使用**Spring data rest时,由于框架自己生成相关接口,处理相关业务就要实现监听才行。要点如下。

1.Listener

@Component
public class TagListener extends AbstractRepositoryEventListener<TagEntity> {
    private final ITagRepository tagRepository;

    public TagListener(ITagRepository tagRepository) {
        this.tagRepository = tagRepository;
    }

    @Override
    protected void onBeforeCreate(TagEntity tag) {
        TagEntity exist = tagRepository.findByName(tag.getName());

        if (exist != null){
            RestVerifyUtils.rejectValue(tag,"name","name.requied","The tag already exist");
        }
        tag.setId(IdUtils.generator());
    }
}

继承AbstractRepositoryEventListener抽象类,重写其中的方法,方法列表如下

  • BeforeCreateEvent
  • AfterCreateEvent
  • BeforeSaveEvent
  • AfterSaveEvent
  • BeforeLinkSaveEvent
  • AfterLinkSaveEvent
  • BeforeDeleteEvent
  • AfterDeleteEvent

2.Validator

@Component
public class TagValidator {
    //beforeCreate+TagEntity+Validator
    //执行时机+实体+Validator
    @Component("beforeCreateTagEntityValidator")
    class TagCreateValidator implements Validator {

        @Override
        public boolean supports(Class<?> clazz) {
            return TagEntity.class.equals(clazz);
        }

        @Override
        public void validate(Object target, Errors errors) {
            ValidationUtils.rejectIfEmpty(errors, "name", "required", "标签名称不能为空");
            ValidationUtils.rejectIfEmpty(errors, "id", "required", "ID生成错误");
        }
    }
}

3.在Listener中抛出异常

Spring data rest 的异常监听是在 ValidatingRepositoryEventListener 中处理的。

private Errors validate(String event, Object entity) {
    if (entity == null) {
        return null;
    }
    Errors errors = new ValidationErrors(entity, persistentEntitiesFactory.getObject());

    for (Validator validator : getValidatorsForEvent(event)) {

        if (validator.supports(entity.getClass())) {
            LOGGER.debug("{}: {} with {}", event, entity, validator);
            ValidationUtils.invokeValidator(validator, entity, errors);
        }
    }
    if (errors.hasErrors()) {
        throw new RepositoryConstraintViolationException(errors);
    }
    return errors;
}

查看源码可以看到抛出RepositoryConstraintViolationException异常需要参数errorserror的生成需要persistentEntitiesFactory

private final ObjectFactory<PersistentEntities> persistentEntitiesFactory;
/**
* Creates a new {@link ValidatingRepositoryEventListener} using the given repositories.
* 
* @param persistentEntitiesFactory must not be {@literal null}.
*/
public ValidatingRepositoryEventListener(ObjectFactory<PersistentEntities> persistentEntitiesFactory) {
    Assert.notNull(persistentEntitiesFactory, "PersistentEntities must not be null!");
    this.persistentEntitiesFactory = persistentEntitiesFactory;
    this.validators = new LinkedMultiValueMap<String, Validator>();
}

跟踪源码发现persistentEntitiesFactory是Spring自动注入的。于是就找到了可以自己封装验证器在Listener中使用。

@Bean
public PersistentEntities persistentEntities(ObjectFactory<PersistentEntities> entitiesObjectFactory) {
    return entitiesObjectFactory.getObject();
}

public class RestVerifyUtils {

    public static void reject(Object target, String errorCode, String message) {
        PersistentEntities entities = SpringUtils.getBean("persistentEntities", PersistentEntities.class);
        Errors errors = new ValidationErrors(target, entities);
        errors.reject(errorCode, message);
        throw new RepositoryConstraintViolationException(errors);
    }

    public static void rejectValue(Object target, String field, String errorCode, String message) {
        PersistentEntities entities = SpringUtils.getBean("persistentEntities", PersistentEntities.class);
        Errors errors = new ValidationErrors(target, entities);
        errors.rejectValue(field, errorCode, message);
        throw new RepositoryConstraintViolationException(errors);
    }

    public static void rejectValueIfNull(Object target, String field, String errorCode, String message) {
        if (target == null) {
            PersistentEntities entities = SpringUtils.getBean("persistentEntities", PersistentEntities.class);
            Errors errors = new ValidationErrors(target, entities);
            errors.rejectValue(field, errorCode, message);
            throw new RepositoryConstraintViolationException(errors);
        }
    }

    public static <T> void rejectIfEmpty(Collection<T> target, String errorCode, String message) {
        if (CollectionUtils.isEmpty(target)) {
            PersistentEntities entities = SpringUtils.getBean("persistentEntities", PersistentEntities.class);
            Errors errors = new ValidationErrors(target, entities);
            errors.reject(errorCode, message);
            throw new RepositoryConstraintViolationException(errors);
        }
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。