2014-06-20 19 views
15

Ich habe versucht, Feder-Validatoren zu einem Feder-Daten-Rest-Projekt hinzuzufügen.Spring-Data-Rest Validator

Ich folgte zusammen und richten Sie die „getting started“ Anwendung über diesen Link: http://spring.io/guides/gs/accessing-data-rest/

... und jetzt versuche ich, indem Sie die Dokumente hier eine benutzerdefinierte PeopleValidator hinzuzufügen: http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/validation-chapter.html

Meine benutzerdefinierte PeopleValidator sieht aus wie

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

... und meine Application.java Klasse sieht nun wie folgt

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

Ich würde erwarten, dass POST an die http://localhost:8080/people URL würde zu einem Fehler irgendeiner Art führen, da der PeopleValidator alles zurückweist. Es wird jedoch kein Fehler ausgegeben und der Validator wird nie aufgerufen.

Ich habe auch versucht, den Validator manuell einzurichten, wie in Abschnitt 5.1 der Dokumentation zur Federdatenablage beschrieben.

Was fehlt mir?

Antwort

11

So scheint es, dass die vor/nach "Speichern" Ereignisse nur das Feuer auf PUT und PATCH. Beim POSTing werden die Vorher/Nachher-Ereignisse ausgelöst.

Ich versuchte es den manuellen Weg wieder mit der configureValidatingRepositoryEventListener überschreiben und es funktionierte. Ich bin mir nicht sicher, was ich bei der Arbeit anders mache als hier zu Hause. Ich muss morgen nachsehen.

Ich würde gerne hören, wenn andere Vorschläge haben, warum es nicht funktionieren würde.

Zur Erinnerung, hier ist, wie die neue Application.java Klasse aussieht.

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

Anscheinend wird das Ereignis "beforeSave" nicht ausgelöst, sondern das Ereignis "beforeCreate". Ich musste es immer noch "manuell" verbinden, anstatt eine Bean namens "beforeCreatePeopleValidator" zu verwenden. –

+0

Ich finde die gleiche Situation, automatische Erkennung funktioniert nicht. – JBCP

+0

Ich habe auch ein ähnliches Problem - manuell Verdrahtung Ereignisse funktioniert gut, automatische Erkennung schlägt fehl. – Mikk

1

Ein bisschen ein Stich im Dunkeln - ich habe spring-data-rest nicht verwendet. Nach dem Lesen des Tutorials, das Sie verfolgen, ist das Problem jedoch, dass Sie ein PersonValidator nicht ein PeopleValidator benötigen. Benennen Sie alles entsprechend:

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

Anwendung

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

Vielen Dank für den Vorschlag. Aber es schien keinen Unterschied zu machen. Ich habe es manuell versucht und es hat funktioniert. Ich werde es bei meinem Projekt erneut versuchen müssen, wenn ich zur Arbeit komme. –

+0

@Muel - wie hast du es getestet? –

2

Sieht aus wie die Funktion ist derzeit nicht implementiert ist (2.3.0), unglücklicherweise gibt es keine Konstanten für die Ereignisnamen sonst die Lösung unter nicht so zerbrechlich sein würde.

Die Configuration fügt alle korrekt benannten Validator Beans zu ValidatingRepositoryEventListener mit dem richtigen Ereignis.

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

Ein anderer Weg, es zu tun ist, kommentierte Handler zu verwenden, wie http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/events-chapter.html#d5e443

Hier hier angegeben ist ein Beispiel dafür, wie kommentierten Handler zu verwenden:

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

Beispiel von github ist bearbeitet für Kürze.