2017-03-13 1 views
0

Ich kann nicht auf Methodenebene Validierung richtig machen. Oder ich verstehe nicht, wie es funktioniert.SpringBoot-Validierung einer Bean-Methode Parameter und Rückgabe

Meine Anwendungsklasse ist unten. Sehr einfach. Es enthält MethodValidationPostProcessor Bean-Definition. Es läuft auch Greeter Service.

@SpringBootApplication 
public class App implements CommandLineRunner { 
    private final Greeter greeter; 

    public App(Greeter greeter) { 
     this.greeter = greeter; 
    } 

    public static void main(String[] args) { 
     new SpringApplicationBuilder().main(App.class).sources(App.class).web(false).run(args).close(); 
    } 

    @Bean 
    public org.springframework.validation.beanvalidation.MethodValidationPostProcessor methodValidationPostProcessor() { 
     return new MethodValidationPostProcessor(); 
    } 

    @Override 
    public void run(String... args) throws Exception { 
     final Input input = new Input(); 
     input.setName("j"); 
     final String messageFromInput = greeter.getMessageFromInput(input); 

     final String messageFromString = greeter.getMessageFromString("j"); 
    } 
} 

Greeter Service unten. Hier erwarte ich, Eingaben und Ausgaben zu validieren.

@Service 
@Validated 
public class Greeter { 
    String getMessageFromInput(@Valid @NotNull Input name) { 
     return "[From Input] Greetings! Oh mighty " + name + "!"; 
    } 

    String getMessageFromString(@Size(min = 4) String name) { 
     return "[From String] Greetings! Oh mighty " + name + "!"; 
    } 
} 

Eingabe DTO ist sehr einfach.

public class Input { 
    @NotEmpty 
    @Size(min = 3) 
    private String name; 

    // Getters, setters and toString ommited. 
} 

Da der Name in beiden Fällen, direkter String und DTO, nur ein Buchstabe ist, erwarte ich, dass diese Einstellung eine Ausnahme auslöst. Leider passiert nichts und die Anwendung wird erfolgreich abgeschlossen. Es funktioniert mit den Methoden des Controllers. Aber ich möchte, dass es mit den Methoden jeder Bean funktioniert.

+1

Verwenden Sie 'Greeter' nicht als Konstruktorargument. Ich schätze, dass dies die frühe Erstellung der Bean auslöst, wodurch sie nicht mehr für die Proxy-Erstellung in Frage kommt und daher die Validierung nicht angewendet wird. Erstellen Sie eine '@ Bean'-Methode, die den' CommandLineRunner' erstellt und stattdessen 'Greeter' als Methodenargument einfügt. Machen Sie Ihre Methoden auch "public", da AOP nur mit öffentlichen Methoden funktioniert. –

+0

Sie haben Recht mit der frühen Bean-Erstellung. Als ich den Runner zu einer Bean-Factory-Methode mit 'Greeter' als Argument bewegte, funktioniert es gut. Es scheint, dass Greeters Zugang zu "öffentlichen" Methoden irrelevant ist. Nun, als Sie darüber gesprochen haben, erinnere ich mich an Informationen in der Log-Datei, die besagen, dass Greeter kein geeigneter Kandidat für einen Proxy ist. Jetzt weiß ich was die Implikationen sind. – waste

Antwort

2

Sie injizieren Ihre Bean als ein Konstruktorargument in die Klasse mit der Bezeichnung @SpringBootApplication, die eine @Configuration Klasse ist. Um diese Abhängigkeit zu erfüllen, wird die sehr früh im Startprozess der ApplicationContext erstellt und als solche wird sie als Kandidat für die Proxy-Erstellung entfernt.

Anstatt es als Konstruktorargument zu injizieren, verschieben Sie Ihre CommandLineRunner Logik in eine mit @Bean annotierte Methode und injizieren Sie einfach die Greeter als Abhängigkeit. Dies verzögert die Erstellung der Bean und macht sie daher für die Proxy-Verarbeitung verfügbar.

@Bean 
public CommandLineRunner runner(Greeter greeter) { 
    return new CommandLineRunner() { 

     @Override 
     public void run(String... args) throws Exception { 
      final Input input = new Input(); 
      input.setName("j"); 
      final String messageFromInput = greeter.getMessageFromInput(input); 

      final String messageFromString = greeter.getMessageFromString("j"); 
     } 
    }; 
} 

Eine andere Sache ist, dass Ihre Methoden des Greeter sollte aufgrund der Art von Proxies sein, public.

Verwandte Themen