弹簧-数据-休息验证器

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

我按照这个链接设置了“入门”应用程序:http://spring.io/guides/gs/accessing-data-rest/

...现在我正在尝试通过遵循此处的文档来添加自定义人员验证器:http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/validation-chapter.html

我的自定义人员验证器看起来像

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");
    }
}

...我的应用程序.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到URL会导致某种错误,因为PeopleValidator拒绝了所有内容。但是,不会引发任何错误,并且永远不会调用验证程序。http://localhost:8080/people

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

我错过了什么?


答案 1

因此,似乎之前/之后的“保存”事件仅在PUT和PATCH上触发。开机自检时,将触发“创建”事件之前/之后的事件。

我再次使用覆盖以手动方式尝试了它,并且它起作用了。我不确定我在工作中与在家做什么不同。我明天就得去看看。configureValidatingRepositoryEventListener

我当然很想听听其他人是否对为什么它不起作用有建议。

为了记录在案,下面是新的应用程序.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());
    }
}

答案 2

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

将所有正确命名的 bean 添加到使用正确的事件。ConfigurationValidatorValidatingRepositoryEventListener

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()));
        }
    }
}

推荐