Spring -Data-Rest Validator
Я пытаюсь добавить валидаторы spring в проект spring -data-rest.
Я последовал за ним и установил приложение "начало работы" по этой ссылке: 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();
}
}
Я бы ожидал, что POSTing на URL http://localhost:8080/people
приведет к ошибке, вызванной тем, что PeopleValidator отклоняет все. Однако ошибка не возникает, и валидатор никогда не вызывается.
Я также попытался вручную настроить валидатор, как показано в разделе 5.1 документа spring -data-rest.
Что мне не хватает?
Ответы
Ответ 1
Таким образом, кажется, что события "до" и "до" не срабатывают только в PUT и PATCH. Когда POSTing, события до/после "создания" срабатывают.
Я снова попробовал его с помощью переопределения 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());
}
}
Ответ 2
Похоже, что функция в настоящее время не реализована (2.3.0), к несчастью, для имен событий нет констант, иначе решение ниже не было бы таким хрупким.
Configuration
добавляет все правильно названные Validator
beans в 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()));
}
}
}
Ответ 3
Немного о голосе в темноте - я не использовал spring-data-rest
. Однако, прочитав учебник, за которым вы следуете, я думаю, проблема в том, что вам нужен PersonValidator
не a 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");
}
}
Применение
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();
}
}
Ответ 4
Другой способ сделать это - использовать аннотированные обработчики, как указано здесь
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 отредактирован для краткости.