java - validate - Validador Spring-Data-Rest
spring rest validation (4)
Así que parece que los eventos de "guardar" antes / después solo se disparan en PUT y PATCH. Al realizar POSTING, se activan los eventos de "crear" antes / después.
Lo intenté de forma manual otra vez utilizando la anulación de configureValidatingRepositoryEventListener
y funcionó. No estoy seguro de lo que hago diferente en el trabajo que aquí en casa. Tendré que mirar mañana.
Me encantaría saber si otros tienen sugerencias sobre por qué no funcionaría.
Para el registro, aquí está el aspecto de la nueva clase 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());
}
}
He estado tratando de agregar validadores de primavera a un proyecto de descanso de datos de primavera.
Seguí y configuré la aplicación "Cómo empezar" a través de este enlace: http://spring.io/guides/gs/accessing-data-rest/
... y ahora estoy tratando de agregar un PeopleValidator personalizado siguiendo los documentos aquí: http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/validation-chapter.html
Mi PeopleValidator personalizado se parece a
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");
}
}
... y mi clase Application.java ahora se ve así
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();
}
}
Espero que el POSTing en la URL http://localhost:8080/people
resulte en algún tipo de error, ya que el PeopleValidator está rechazando todo. Sin embargo, no se produce ningún error y nunca se llama al validador.
También he intentado configurar manualmente el validador como se muestra en la sección 5.1 de la documentación de spring-data-rest.
¿Qué me estoy perdiendo?
Otra forma de hacerlo es usar controladores anotados como se especifica aquí http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/events-chapter.html#d5e443
Aquí hay un ejemplo de cómo usar manejadores anotados:
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");
}
}
El ejemplo es de github editado por brevedad.
Parece que la función no está implementada actualmente (2.3.0), desafortunadamente no hay constantes para los nombres de los eventos, de lo contrario, la solución a continuación no sería tan frágil.
La Configuration
agrega todos los beans Validator
con el nombre correcto a ValidatingRepositoryEventListener
usando el evento correcto.
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()));
}
}
}
Un poco de una puñalada en la oscuridad, no he usado spring-data-rest
. Sin embargo, después de leer el tutorial que está siguiendo, creo que el problema es que necesita un PersonValidator
no un PeopleValidator
. Renombra todo en consecuencia:
Validador de personas
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");
}
}
Solicitud
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();
}
}