首页 文章

Spring-Data-Rest验证器

提问于
浏览
16

我一直在尝试将 spring 验证器添加到spring-data-rest项目中 .

我跟着并通过以下链接设置"getting started"应用程序:http://spring.io/guides/gs/accessing-data-rest/

...现在我正在尝试通过以下文档添加自定义PeopleValidator:http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/validation-chapter.html

我的自定义PeopleValidator看起来像

package hello;

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

public class PeopleValidator implements Validator {
    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }

    @Override
    public void validate(Object target, Errors errors) {
        errors.reject("DIE");
    }
}

...而我的Application.java类现在看起来像这样

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;

@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public PeopleValidator beforeCreatePeopleValidator() {
        return new PeopleValidator();
    }
}

我希望POST到 http://localhost:8080/people URL会导致某种错误,因为PeopleValidator拒绝了所有内容 . 但是,不会抛出任何错误,并且永远不会调用验证程序 .

我还尝试过手动设置验证器,如spring-data-rest文档的5.1节所示 .

我错过了什么?

4 回答

  • 1

    因此,看起来前/后“保存”事件仅在PUT和PATCH上触发 . POST时,“创建”事件之前/之后触发 .

    我使用 configureValidatingRepositoryEventListener 覆盖再次尝试手动方式,它工作 . 我在工作上做的不同于在家里做的事情 . 我明天要看 .

    我肯定会喜欢听到其他人是否有关于为什么它不起作用的建议 .

    对于记录,这是新的Application.java类的样子 .

    package hello;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Import;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
    import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
    
    @Configuration
    @EnableJpaRepositories
    @Import(RepositoryRestMvcConfiguration.class)
    @EnableAutoConfiguration
    public class Application extends RepositoryRestMvcConfiguration {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
        @Override
        protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
            validatingListener.addValidator("beforeCreate", new PeopleValidator());
        }
    }
    
  • 3

    看起来该功能目前尚未实现(2.3.0),不幸的是,事件名称没有常量,否则下面的解决方案不会那么脆弱 .

    Configuration 使用正确的事件将所有正确命名的 Validator bean添加到 ValidatingRepositoryEventListener .

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.beans.factory.ListableBeanFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
    import org.springframework.validation.Validator;
    
    @Configuration
    public class ValidatorRegistrar implements InitializingBean {
    
        private static final List<String> EVENTS;
        static {
            List<String> events = new ArrayList<String>();
            events.add("beforeCreate");
            events.add("afterCreate");
            events.add("beforeSave");
            events.add("afterSave");
            events.add("beforeLinkSave");
            events.add("afterLinkSave");
            events.add("beforeDelete");
            events.add("afterDelete");
            EVENTS = Collections.unmodifiableList(events);
        }
    
        @Autowired
        ListableBeanFactory beanFactory;
    
        @Autowired
        ValidatingRepositoryEventListener validatingRepositoryEventListener;
    
        @Override
        public void afterPropertiesSet() throws Exception {
            Map<String, Validator> validators = beanFactory.getBeansOfType(Validator.class);
            for (Map.Entry<String, Validator> entry : validators.entrySet()) {
                EVENTS.stream().filter(p -> entry.getKey().startsWith(p)).findFirst()
                        .ifPresent(p -> validatingRepositoryEventListener.addValidator(p, entry.getValue()));
            }
        }
    }
    
  • 11

    在黑暗中有点刺 - 我没用 spring-data-rest . 但是,在阅读了您正在阅读的教程之后,我认为问题是您需要 PersonValidator 而不是 PeopleValidator . 相应地重命名一切:

    PersonValidator

    package hello;
    
    import org.springframework.validation.Errors;
    import org.springframework.validation.Validator;
    
    public class PersonValidator implements Validator {
        @Override
        public boolean supports(Class<?> clazz) {
            return true;
        }
    
        @Override
        public void validate(Object target, Errors errors) {
            errors.reject("DIE");
        }
    }
    

    Application

    package hello;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Import;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
    
    @Configuration
    @EnableJpaRepositories
    @Import(RepositoryRestMvcConfiguration.class)
    @EnableAutoConfiguration
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
        @Bean
        public PersonValidator beforeCreatePersonValidator() {
            return new PersonValidator();
        }
    }
    
  • 0

    另一种方法是使用此处指定的带注释的处理程序http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/events-chapter.html#d5e443

    以下是如何使用带注释的处理程序的示例:

    import gr.bytecode.restapp.model.Agent;
    import org.springframework.data.rest.core.annotation.HandleBeforeCreate;
    import org.springframework.data.rest.core.annotation.HandleBeforeSave;
    import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
    import org.springframework.stereotype.Component;
    
    @Component
    @RepositoryEventHandler(Agent.class)
    public class AgentEventHandler {
    
        public static final String NEW_NAME = "**modified**";
    
        @HandleBeforeCreate
        public void handleBeforeCreates(Agent agent) {
                agent.setName(NEW_NAME);
        }
    
        @HandleBeforeSave
        public void handleBeforeSave(Agent agent) {
            agent.setName(NEW_NAME + "..update");
        }
    }
    

    示例来自github,为简洁起见 .

相关问题