Bonsoir amis développeurs,
(Contexte - Vous pouvez vous rediriger vers la section Demande si vous ne souhaitez pas perdre de temps.)
Récemment, j'ai suivi de nombreux tutoriels pour me lancer dans la création d'un site internet en J2EE.
Basée sur les Frameworks Spring, Hibernate et Primefaces, l'application évolue lentement mais sûrement...
C'est alors que j'ai été confronté à l'utilisation des annotations avec Spring.
J'ai vu de nombreux sujets sur le forum developpez.net qui parlaient de ses fameuses annotations, et ai pu rectifier quelques erreurs.
Typiquement, je n'avais pas activé la gestion des annotations dans Spring.
Malgré le parcours de X tutoriels sur Spring, je ne parviens toujours pas à faire fonctionner les annotations d'injection.
J'ai ajouté ces deux lignes dans le fichier de configuration de Spring (applicationContext.xml) :
Je n'ai pas déclaré ces balises ailleurs (car apparemment cela pose problème de scanner plusieurs fois le projet).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 <context:component-scan base-package="com.mickaelcalmettes.siteweb" /> <context:annotation-config />
(Demande)
Concrètement, j'ai annoté tous mes DAOImpl avec l'annotation @Repository("nomDuDAO"), tous mes ServiceImpl avec l'annotation @Service("nomDuService"), et toutes mes références aux IDAO et IServices avec @Autowired.
J'ai créé un backing bean qui appelle un service de test, et lors de cet appel, je reçois un NullPointerException.
Les détails ci-après.
(Informations sur le code)
La vue :
Ces boutons appelent le backingBean "TestHibernateBean" :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 <h:commandButton value="Test création catégorie avec todos inexistants" action="#{testHibernateBean.creerCategorie()}" /> <h:commandButton value="Test création todo avec une catégorie inexistante" action="#{testHibernateBean.creerTodo()}" />
Lors de l'appel de l'une des deux méthodes creerCategorie() ou creerTodo(), Spring ne parvient pas à retrouver le service appelé malgré les annotations.
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 @ManagedBean(name = "testHibernateBean") @ViewScoped public class TestHibernateBean implements Serializable { private Categorie categorie1; private final Set<TodoMemo> todoSet = new HashSet(); private TodoMemo todo; private Categorie categorie2; @Autowired private ITodoService todoService; @Autowired private ICategorieService categorieService; @PostConstruct public void init() { this.initTests(); } private void initTests() { // Création du jeu de données categorie1 = new Categorie(); categorie2 = new Categorie(); categorie1.setLibelleCategorie("Catégorie avec plusieurs TODO"); categorie2.setLibelleCategorie("Catégorie avec un seul TODO"); todo = new TodoMemo(); todo.setDateTodo(new Date()); todo.setPriorite(5); todo.setTodo("Todo relié à la catégorie 'Catégorie avec un seul TODO'"); for(int i=1 ; i<5 ; i++){ TodoMemo tempTodo = new TodoMemo(); tempTodo.setDateTodo(new Date()); tempTodo.setPriorite(i); tempTodo.setTodo("Todo relié à la catégorie 'Catégorie avec plusieurs TODO' n°" + i); todoSet.add(tempTodo); } // Liaisons categorie1.setTodo(todoSet); todo.setCategorie(categorie2); } public void creerCategorie(){ // Test création catégorie avec plusieurs TODO associés categorieService.saveCategorie(categorie1); } public void creerTodo(){ // Test création todo avec catégorie associée todoService.saveTodo(todo); } public Categorie getCategorie1() { return categorie1; } public void setCategorie1(Categorie categorie1) { this.categorie1 = categorie1; } public TodoMemo getTodo() { return todo; } public void setTodo(TodoMemo todo) { this.todo = todo; } public Categorie getCategorie2() { return categorie2; } public void setCategorie2(Categorie categorie2) { this.categorie2 = categorie2; } public ITodoService getTodoService() { return todoService; } public void setTodoService(ITodoService todoService) { this.todoService = todoService; } public ICategorieService getCategorieService() { return categorieService; } public void setCategorieService(ICategorieService categorieService) { this.categorieService = categorieService; } }
Il me génère un NullPointerException (au besoin je peux insérer la trace de l'erreur). J'ai testé d'appeler le service via le service implémenté (CategorieServiceImpl par exemple), et il n'y a plus d'erreur. Enfin, si, mais le NullPointerException se génère dans le service lors de l'appel du DAO.
Voici l'interface du service "ICategorieService" :
Voici le service "CategorieServiceImpl" qui devrait être appelé par Spring grâce aux annotations :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 public interface ICategorieService { public void saveCategorie(Categorie categorie); }
Et enfin, voici les fichiers de configuration.
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 @Service("categorieService") public class CategorieServiceImpl implements ICategorieService { @Autowired ICategorieDAO categorieDAO; @Override public void saveCategorie(Categorie categorie) { categorieDAO.saveCategorie(categorie); } public ICategorieDAO getCategorieDAO() { return categorieDAO; } public void setCategorieDAO(ICategorieDAO categorieDAO) { this.categorieDAO = categorieDAO; } }
"applicationContext.xml" :
"dispatcher-servlet.xml" : Je ne me sers pas de ce fichier de configuration, il a été créé automatiquement par Netbeans. Je peux fournir le code au besoin.
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 <?xml version='1.0' encoding='UTF-8' ?> <!-- was: <?xml version="1.0" encoding="UTF-8"?> --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <context:component-scan base-package="com.mickaelcalmettes.siteweb" /> <context:annotation-config /> <!-- <bean id="categorieDAO" class="com.mickaelcalmettes.siteweb.dao.impl.CategorieDAOImpl" /> <bean id="todoDAO" class="com.mickaelcalmettes.siteweb.dao.impl.TodoDAOImpl" /> <bean id="categorieService" class="com.mickaelcalmettes.siteweb.services.impl.CategorieServiceImpl" /> <bean id="todoService" class="com.mickaelcalmettes.siteweb.services.impl.TodoServiceImpl" />--> </beans>
"web.xml" :
Merci beaucoup par avance de votre aide.
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
44 <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <context-param> <param-name>CONFIG_PATH</param-name> <param-value>/WEB-INF</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>Pages/Tests/pageTestTemplateAccueil.xhtml</welcome-file> </welcome-file-list> </web-app>
Je m'excuse de la longueur du message, je tenais à le rendre le plus clair possible.
En vous souhaitant une agréable soirée,
M20K8X.
Partager