2017-03-13 2 views
0

Je ne peux pas valider correctement le niveau de méthode. Ou je ne comprends pas comment cela fonctionne.Validation SpringBoot d'un paramètre de méthode de bean et retour

Ma classe d'application est ci-dessous. Très simple. Il contient la définition de haricot MethodValidationPostProcessor. Il exécute également le service Greeter.

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

Service de greffe ci-dessous. Ici, je m'attends à valider l'entrée et la sortie.

@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 + "!"; 
    } 
} 

L'entrée DTO est également très simple. Comme le nom dans les deux cas, direct String et DTO, est seulement une lettre, je m'attends à ce que cette configuration rejette une exception. Malheureusement, rien ne se passe et l'application se termine avec succès. Cela fonctionne avec les méthodes du contrôleur. Mais je voudrais qu'il fonctionne avec les méthodes de n'importe quel haricot.

+1

Ne pas utiliser 'Greeter' comme argument constructeur. Je suppose que cela déclenche la création précoce du bean, ce qui ne le rend plus candidat à la création de proxy et donc la validation n'est pas appliquée. Créez une méthode '@ Bean' qui crée le' CommandLineRunner' et injectez le 'Greeter' comme argument de méthode à la place. Faites également vos méthodes 'public' comme AOP ne fonctionnera que sur les méthodes publiques. –

+0

Vous avez raison à propos de la création de haricots précoces. Lorsque j'ai déplacé le coureur vers une méthode d'usine de haricots avec «Greeter» comme argument, cela fonctionne très bien. Il semble que l'accès des méthodes 'publiques' de Greeter ne soit pas pertinent. Maintenant, quand vous avez mentionné à ce sujet, je me souviens d'informations dans le fichier journal en disant que Greeter n'est pas un candidat éligible pour proxy. Maintenant, je sais quelles sont les implications. – waste

Répondre

2

Vous injectez votre bean Greeter en tant qu'argument de constructeur dans la classe annotée avec @SpringBootApplication qui est une classe @Configuration. Pour satisfaire cette dépendance, le Greeter est créé très tôt dans le processus de démarrage du ApplicationContext et en tant que tel le supprimera en tant que candidat pour la création de proxy. Au lieu de l'injecter comme argument constructeur, déplacez votre logique CommandLineRunner vers une méthode annotée @Bean et injectez simplement le Greeter en tant que dépendance. Cela va retarder la création du bean et en tant que tel, le rendre disponible pour le mandataire.

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

Une autre chose est que vos méthodes de Greeter devraient être, en raison de la nature de la procuration, public.