IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Spring Java Discussion :

[@Controller][Validator] Injecter un service depuis un validator


Sujet :

Spring Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 51
    Par défaut [@Controller][Validator] Injecter un service depuis un validator
    Bonsoir à tous,

    Je suis entrain de galérer sur l'injection d'un service depuis une classe validator :
    Voici ma classe service :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    @Service("PersonService")
    public class PersonServiceImpl implements PersonService {
     
    	@Autowired
    	private PersonDao dao;
     
    	public void setDao(PersonDao dao) {
    		this.dao = dao;
    	}
     
    	...
    Voici mon contrôleur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    @Controller
    @SessionAttributes("person")
    public class PersonController {
     
    	@Autowired
    	private PersonService service;
     
    	public void setService(PersonService service) {
    		this.service = service;
    	}
     
    @RequestMapping(value = "/form.html", method = RequestMethod.POST)
    	public String submit(@ModelAttribute("person")Person person, BindingResult result, SessionStatus status) { 
     
    		new PersonValidator().validate(person, result);
    		if (result.hasErrors()) {
    			return "form";
    		} else {
    			service.saveOrUpdate(person);
    			status.setComplete(); 
    			return "redirect:list.html";
    		}
    	}
    Je voudrais tester si la personne existe déjà dans la base de données avant de la rajouter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    public class PersonValidator implements Validator {
     
    	@Autowired
    	private PersonService service;
     
    	public void setService(PersonService service) {
    		this.service = service;
    	}
     
    	public boolean supports(Class clazz) {
    		return false;
    	}
     
    	public void validate(Object object, Errors errors) {
    		 Person p = (Person) object;
    		 System.out.println("dans le validate : "+p.getNom());
    		 	if(service.userExists(p.getNom())){
    				errors.rejectValue("nom","errors.required", null,"Username already taken.");
    			}
    	}
    J'ai un java.lang.NullPointerException sur la variable service quand j'invoque la méthode service.userExists(p.getNom()) de la couche
    Pourtant l'objet p n'est pas a null, j'ai vérifié il est bien remplit par l'interface.
    Ce qui est bizarre est que si je désactive cette ligne, la méthode service.saveOrUpdate(person); du contrôleur s'exécute parfaitement => le contrôleur arrive bien a injecter le service et pas le validator !


    Voici la stack error :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    GRAVE: "Servlet.service()" pour la servlet spring a g�n�r� une exception
    java.lang.NullPointerException
    	at spring.tutorial.web.PersonValidator.validate(PersonValidator.java:36)
    	at spring.tutorial.web.PersonController.submit(PersonController.java:88)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:160)
    	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:245)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:874)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:808)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:476)
    	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:441)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    	at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
    	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    	at java.lang.Thread.run(Unknown Source)
    j'ai rajouté cette ligne dans le spring-config.xml

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <bean id="configurationLoader"		class="org.springmodules.validation.bean.conf.loader.annotation.AnnotationBeanValidationConfigurationLoader" />
    	<bean id="validator"
    		class="org.springmodules.validation.bean.BeanValidator"
    		p:configurationLoader-ref="configurationLoader" />

    Auriez-vous une idée pourquoi je n'arrive pas à injecter le service dans ma classe Validator ?

    Merci par avance de votre aide.

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 51
    Par défaut Problème Résolut !
    Bon,
    Je me répond à moi même pour ceux qui sont intéressés par la solution que j'ai trouvé :

    J'ai utilisé le constructeur de ma classe PersonValidator pour passer une référence vers le PersonService :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    @Controller
    @SessionAttributes("person")
    public class PersonController {
     
    	@Autowired
    	private PersonService service;
     
    	public void setService(PersonService service) {
    		this.service = service;
    	}
     
     
    @RequestMapping(value = "/form.html", method = RequestMethod.POST)
    	public String submit(@ModelAttribute("person")Person person, BindingResult result, SessionStatus status) { 
     
    //Passer une référence du service dans le constructeur
    		new PersonValidator(service).validate(person, result);
    		...
    	}
    Et dans la classe Validator :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public class PersonValidator implements Validator {
     
    	public PersonService service;
     
    	public PersonValidator(PersonService service) {
    	    this.service = service;
    	}
     
            public void validate(Object object, Errors errors) {
    		 Person p = (Person) object;
     
                             //Maintenant l'invocation de la fonction userExists marche
    		 	if(service.userExists(p.getNom())){

    Avez-vous une meilleure solution ?

    Merci.

  3. #3
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par hkefi Voir le message

    Avez-vous une meilleure solution ?

    Merci.
    le fait que le Validator ait besoin de connaître le service est - à mon sens - un problème de design de votre architecture…

    le rôle d'un Validator devrait être limité à la validation d'un object en lui-même sans tenir compte de contraintes contextuelles…

    service "création d'un nouvel individu" =
    1. validation de son contenu propre via le Validator,
    2. si 1 OK alors vérification de sa pertinence (par exemple unicité) via le DAO

    si vous aviez bien séparé les responsabilités, le problème de l'injection du service dans le validator ne se serait donc même pas posé car elle n'a pas lieu d'être…

    ce que vous faites c'est :
    "le service qui demande au validator qui demande au service de demander au dao de vérifier l'unicité…"

  4. #4
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Par défaut
    Le soucis est ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @RequestMapping(value = "/form.html", method = RequestMethod.POST)
    	public String submit(@ModelAttribute("person")Person person, BindingResult result, SessionStatus status) { 
    		
    		new PersonValidator().validate(person, result);
    		if (result.hasErrors()) {
    			return "form";
    		} else {
    			service.saveOrUpdate(person);
    			status.setComplete(); 
    			return "redirect:list.html";
    		}
    	}
    Le fait de faire un new PersoValidator(), ce n'est pas Spring qui va l'instancier, et donc Spring ne fait pas le wiring.
    Donc ton service est 'null'.

    Ta solution corrige cela evidemment.
    L'autre moyen est de te faire injecter le validator dans le controlleur, dans ce cas la, l'injection du service sera réalisée dans le validator aussi
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 51
    Par défaut injecter le validator dans le controlleur
    Merci pour vos réponses,
    Pour répondre à JeitEmgie, j'ai bien séparé les couches et je pouvais pas faire la vérification de l'unicité après la validation du contenu propre par ce que je pourrais plus retourner une erreur ! a moins que tu as une solution à me proposer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    @RequestMapping(value = "/form.html", method = RequestMethod.POST)
    	public String submit(@ModelAttribute("person")Person person, BindingResult result, SessionStatus status) { 
     
    		new PersonValidator().validate(person, result);
     
    // a ce niveau je peux vérifier l'unicité mais je ne peux plus remplir result.hasErrors()
    		if (result.hasErrors()) {
    			return "form";
    		} else {
     
    			service.saveOrUpdate(person);
    			status.setComplete(); 
    			return "redirect:list.html";
    		}
    	}
    mais je voudrais rebondir sur la remarque de Hikage :

    L'autre moyen est de te faire injecter le validator dans le controlleur, dans ce cas la, l'injection du service sera réalisée dans le validator aussi
    Justement, comment injecter le validator dans le controlleur ?
    Les exemples que j'ai trouvé appellent tous le validateur en passant par un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    new PersonValidator().validate(person, result);
    Merci

  6. #6
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Par défaut
    As tu essayé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	@Autowired
    	private PersonValidator validator;
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 51
    Par défaut Ca marche pas
    Je viens de faire comme tu m'as dit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    @Controller
    @SessionAttributes("person")
    public class PersonController {
     
    	@Autowired
    	private PersonService service;
     
    	public void setService(PersonService service) {
    		this.service = service;
    	}
     
    	@Autowired
    	public PersonValidator validator;
     
    	public void setValidator(PersonValidator validator) {
    	    this.validator = validator;
    	}
     
    @RequestMapping(value = "/form.html", method = RequestMethod.POST)
    	public String submit(@ModelAttribute("person")Person person, BindingResult result, SessionStatus status) { 
    	    validator.validate(person, result);
    		if (result.hasErrors()) {
    			return "form";
    		} else {
    			service.saveOrUpdate(person);
    			status.setComplete(); 
    			return "redirect:list.html";
    		}
    	}
    Et dans la classe Valildator :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public class PersonValidator implements Validator {
     
        	@Autowired
    	public PersonService service;
     
    	public void setService(PersonService service) {
    		this.service = service;
    	}
    J'ai une grosse stack : No unique bean of type PersonValidator is defined:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    2009-01-05 14:26:06,809 ERROR [org.springframework.web.context.ContextLoader] - <Context initialization failed>
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personController': Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public spring.tutorial.web.validator.PersonValidator spring.tutorial.web.PersonController.validator; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [spring.tutorial.web.validator.PersonValidator] is defined: Unsatisfied dependency of type [class spring.tutorial.web.validator.PersonValidator]: expected at least 1 matching bean
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:231)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:978)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:485)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:455)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:169)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:170)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:413)
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:735)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:369)
    	at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:251)
    	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:190)
    	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
    	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
    	at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
    	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
    	at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
    	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
    	at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
    	at org.apache.catalina.core.StandardService.start(StandardService.java:516)
    	at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
    	at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:585)
    	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
    	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public spring.tutorial.web.validator.PersonValidator spring.tutorial.web.PersonController.validator; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [spring.tutorial.web.validator.PersonValidator] is defined: Unsatisfied dependency of type [class spring.tutorial.web.validator.PersonValidator]: expected at least 1 matching bean
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredElement.inject(AutowiredAnnotationBeanPostProcessor.java:375)
    	at org.springframework.beans.factory.annotation.InjectionMetadata.injectFields(InjectionMetadata.java:61)
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:228)
    	... 30 more
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [spring.tutorial.web.validator.PersonValidator] is defined: Unsatisfied dependency of type [class spring.tutorial.web.validator.PersonValidator]: expected at least 1 matching bean
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveDependency(AbstractAutowireCapableBeanFactory.java:417)
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredElement.inject(AutowiredAnnotationBeanPostProcessor.java:361)
    	... 32 more
    Merci

  8. #8
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Par défaut
    Apparemment tu aurais plusieurs bean de classe PersonValidator défini dans ton contexte spring
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 51
    Par défaut
    En fait j'utilise également dans le projet la validation par annotation :

    /***********Spring-config.xml **************
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <!-- Enable annotation-based validation using Bean Validation Framework -->
    	<!-- Using these instead of vld namespace to prevent Eclipse from complaining -->
    	<bean id="configurationLoader"
    		class="org.springmodules.validation.bean.conf.loader.annotation.AnnotationBeanValidationConfigurationLoader" />
    	<bean id="validator"
    		class="org.springmodules.validation.bean.BeanValidator"
    		p:configurationLoader-ref="configurationLoader" />
    /*************ENTITY*****************/

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    @Entity
    @AccessType("field")
    public class UserMessage {
    	   private static final int NAME_MAX_LENGTH = 5;
     
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private long id;
     
    	@NotBlank
    	@Length(min=1, max = NAME_MAX_LENGTH)
    	private String name;
     
    	@NotBlank
    	@Email(applyIf = "email is not blank")
    	@Length(max = 80)
    	private String email;
    Lorsque j'ai changé le nom de la variable validator, j'ai remarqué qu'il fait confusion entre validator et pvalidator :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    @Controller
    @SessionAttributes("person")
    public class PersonController {
     
    	@Autowired
    	private PersonService service;
     
    	public void setService(PersonService service) {
    		this.service = service;
    	}
     
    	@Autowired
    	public PersonValidator pvalidator;
     
    	public void setValidator(PersonValidator pvalidator) {
    	    this.pvalidator = pvalidator;
    	}
    Voici l'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    2009-01-05 14:50:11,869 ERROR [org.springframework.web.context.ContextLoader] - <Context initialization failed>
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactController': Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.validation.Validator spring.tutorial.web.ContactController.validator; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.springframework.validation.Validator] is defined: expected single matching bean but found 2: [personValidator, validator]
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:231)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:978)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:485)
    	at java.security.AccessController.doPrivileged(Native Method)
    Voici le 2eme controlleur qui utilise la validation par annotation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    @Controller
    @SessionAttributes("userMessage")
    @RequestMapping("/userform.html")
    public class ContactController {
     
    	@Autowired
    	private UserMessageDao dao;
     
    	@Autowired
    	private Validator validator;
     
    	public void setValidator(Validator validator) {
    		this.validator = validator;
    	}
    Même avec une annotation @Resource ca passe pas !
    Merci

  10. #10
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Par défaut
    C'est logique en fait .. Si tu veux faire de l'injection 'autowired' tu ne peux pas avoir plusieurs Bean du type que tu veux injecter.

    Ici tu veux injecter un 'Validator'. Or tout les validator sont des validators donc tu as ce soucis.

    Dans les Controlleur, utiliser directement ta classe ( PersonValidator, AutrechoseValidator ) et non l'interface Validator
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 51
    Par défaut
    C'est logique en fait .. Si tu veux faire de l'injection 'autowired' tu ne peux pas avoir plusieurs Bean du type que tu veux injecter.

    Ici tu veux injecter un 'Validator'. Or tout les validator sont des validators donc tu as ce soucis.
    Je suis d'accord avec toi mais si je veux mixer les 2 comment dois-je faire ?

    1- L'interface Validator avec les annotations pour valider les champs

    2- Mes classes PersonValidator, AutrechoseValidator pour valider par exmeple l'existance d'un objet dans la base, son unicité, etc.

    Dans les Controlleur, utiliser directement ta classe ( PersonValidator, AutrechoseValidator ) et non l'interface Validator
    Sans passer par l'injection ?
    Ca reviens à ce que j'ai fais au début non passer par le constructeur ?

    Peux-tu me montrer STP comment faire en 2 lignes ?
    Merci

  12. #12
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Par défaut
    Non ce que je veux dire, c'est que tes champs injecté ( @Autowired ) doivent être du type classe PersonValidator ou autre, et non de type Interface Validator.

    Ou alors tu ajoute un @Qualifier('PersonValidator') sur le champs en plus.
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 51
    Par défaut
    Si j'ai bien compris, je dois faire ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    @Component("PersonValidator")
    public class PersonValidator implements Validator {
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    @Controller
    @SessionAttributes("person")
    public class PersonController {
     
    	@Autowired
    	private PersonService service;
     
    	public void setService(PersonService service) {
    		this.service = service;
    	}
     
    	@Qualifier("PersonValidator")
    	private PersonValidator pvalidator;
    Mais malheureusement j'ai tj la même erreur !

  14. #14
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Par défaut
    Oui mais il faut le faire sur tout les controlleurs..


    Dans ta dernière stacktrace, c'était ContactController qui posait le problème.



    2009-01-05 14:50:11,869 ERROR [org.springframework.web.context.ContextLoader] - <Context initialization failed>
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactController': Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.validation.Validator spring.tutorial.web.ContactController.validator; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.springframework.validation.Validator] is defined: expected single matching bean but found 2: [personValidator, validator]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:231)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:978)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:485)
    at java.security.AccessController.doPrivileged(Native Method)

    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 51
    Par défaut
    Justement dans ma classe ContactController j'ai fait la même chose mais j'ai tj la même erreur, il me détecte tous les validateurs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    @Controller
    @SessionAttributes("userMessage")
    @RequestMapping("/userform.html")
    public class ContactController {
     
    	@Autowired
    	private UserMessageDao dao;
     
    	@Autowired
    	private Validator validator;
     
    	public void setValidator(Validator validator) {
    		this.validator = validator;
    	}
     
    	@Qualifier("ContactValidator")
    	private ContactValidator cvalidator;
     
    	public void setCvalidator(ContactValidator cvalidator) {
    	    this.cvalidator = cvalidator;
    	}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    GRAVE: Exception lors de l'envoi de l'�v�nement contexte initialis� (context initialized) � l'instance de classe d'�coute (listener) org.springframework.web.context.ContextLoaderListener
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactController': Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.validation.Validator spring.tutorial.web.ContactController.validator; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.springframework.validation.Validator] is defined: expected single matching bean but found 3: [ContactValidator, PersonValidator, validator]
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:231)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:978)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:485)
    	at java.security.AccessController.doPrivileged(Native Method)

  16. #16
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Par défaut
    Oui mais il reste un 'Validator' ( type Interface )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    @Controller
    @SessionAttributes("userMessage")
    @RequestMapping("/userform.html")
    public class ContactController {
     
    	@Autowired
    	private UserMessageDao dao;
     
    	@Autowired
    	private Validator validator;
     
    	public void setValidator(Validator validator) {
    		this.validator = validator;
    	}
    	
    	@Qualifier("ContactValidator")
    	private ContactValidator cvalidator;
    	
    	public void setCvalidator(ContactValidator cvalidator) {
    	    this.cvalidator = cvalidator;
    	}
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 51
    Par défaut
    Excuse moi je ne te comprends pas, qu'est-ce que il faut faire pour cette interface Validator ? lui rajouter un @Qualifier ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @Controller
    @SessionAttributes("userMessage")
    @RequestMapping("/userform.html")
    public class ContactController {
     
    	@Autowired
    	private UserMessageDao dao;
     
    	@Autowired
    	private Validator validator;
     
    	public void setValidator(Validator validator) {
    		this.validator = validator;
    	}
    	
    	@Qualifier("ContactValidator")
    	private ContactValidator cvalidator;
    	
    	public void setCvalidator(ContactValidator cvalidator) {
    	    this.cvalidator = cvalidator;
    	}

  18. #18
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Par défaut
    Oui.

    Prenons le cas de PersonValidator et qu'il n'y existe qu'un seul bean de type PersonValidator dans ton contexte. Alors tu fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    @Autowired 
    PersonValidator validator

    Si tu veux absolument utiliser Validator comme type, tu fais ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    @Qualifier('LeNomDuBean')
    @Autowired 
    Validator validator

    Sinon spring ne sait pas lequel Validator il doit utiliser
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 51
    Par défaut
    Je comprends très bien ce que tu me dis, sauf je vois pour PersonValidator et ContactValidator mais pas pour la variable validateur qui est de type interface Spring org.springframework.validation.Validator

    J'ai essayé ceci mais tj rien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    public class ContactController {
     
    	@Autowired
    	private UserMessageDao dao;
     
     
    	@Qualifier("ContactValidator")
    	@Autowired 
    	private ContactValidator cvalidator;
     
     
    	public void setPvalidator(ContactValidator cvalidator) {
    	    this.cvalidator = cvalidator;
    	}
     
    	@Qualifier("Validator") // je ne pense pas que c'est correcte ceci
    	@Autowired 
    	private Validator validator;
     
    	public void setValidator(Validator validator) {
    		this.validator = validator;
    	}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    INFO: Initializing Spring root WebApplicationContext
    2009-01-05 15:56:35,943 ERROR [org.springframework.web.context.ContextLoader] - <Context initialization failed>
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactController': Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.validation.Validator spring.tutorial.web.ContactController.validator; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.springframework.validation.Validator] is defined: Unsatisfied dependency of type [interface org.springframework.validation.Validator]: expected at least 1 matching bean
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:231)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:978)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:485)
    	at java.security.AccessController.doPrivileged(Native Method)

  20. #20
    Rédacteur
    Avatar de Hikage
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 177
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 177
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	@Qualifier("Validator") // je ne pense pas que c'est correcte ceci
    	@Autowired 
    	private Validator validator;
    Il faut qu'il y ait un bean nommé Validator pour cela.
    Est-ce le cas ?
    Hikage
    SCJP / SCWCD & SCWSJD Certified / Spring Framework Certified
    [Personal Web] [CV]

    F.A.Q Spring Framework - Participez !

Discussions similaires

  1. Réponses: 1
    Dernier message: 15/09/2011, 17h21
  2. controle de saisie d'une adresse email valide
    Par nassing dans le forum jQuery
    Réponses: 1
    Dernier message: 26/05/2011, 14h52
  3. [AC-2007] Valider une liste multiple depuis un bouton du Ruban
    Par curt dans le forum IHM
    Réponses: 1
    Dernier message: 05/06/2009, 23h38
  4. URL web service est il valide?
    Par Mr_Welby dans le forum Services Web
    Réponses: 1
    Dernier message: 05/09/2007, 18h08
  5. [validation]Erreur format texte depuis BDD
    Par Death83 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 18/02/2006, 19h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo