Initialisation du Projet et Gestion des Dépendances
La première étape consiste à créer un projet Java Web standard et à structurer les packages selon une architecture en couches (modèle, persistance, service, contrôleur). Ensuite, il faut intégrer les bibliothèques nécessaires (Spring Framework, MyBatis, connecteur MySQL, etc.) dans le répertoire lib ou via un gestionnaire de dépendances comme Maven.
Configuration du Contexte Spring et de MyBatis
Dans le package de configuration, nous définissons deux fichiers XML principaux. Le premier gère le routeur Spring MVC, et le second configure la source de données, la session MyBatis et le gestionnaire de transactions.
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.example.app.controller" />
<mvc:annotation-driven />
</beans>
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="sourceDonnees" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/app_db" />
<property name="username" value="admin" />
<property name="password" value="securePass123" />
</bean>
<bean id="fabriqueSql" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="sourceDonnees" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.app.persistence" />
<property name="sqlSessionFactoryBeanName" value="fabriqueSql" />
</bean>
<bean id="gestionnaireTransactions" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="sourceDonnees" />
</bean>
<tx:annotation-driven transaction-manager="gestionnaireTransactions" />
</beans>
Configuration du Descripteur de Déploiement Web
Le fichier web.xml sert à initialiser le contexte de l'application Spring et à mapper le contrôleur frontal DispatcherServlet. Il inclut également un filtre pour l'encodage des caractères.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:config/application-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:config/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appDispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>filterEncodage</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>filterEncodage</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Modélisation de la Base de Données et Couche de Persistance
Après avoir créé la base de données app_db et la table app_user, nous définissons les entités et les interfaces de mappage. Les noms de variables et la structure ont été adaptés pour refléter les bonnes pratiques modernes.
package com.example.app.model;
import java.time.LocalDateTime;
public class AppUser {
private Long id;
private String username;
private String password;
private String fullName;
private LocalDateTime createdAt;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getFullName() { return fullName; }
public void setFullName(String fullName) { this.fullName = fullName; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}
package com.example.app.persistence;
import com.example.app.model.AppUser;
import java.util.List;
public interface UserRepository {
List<AppUser> findAllUsers();
AppUser findById(Long id);
void insertUser(AppUser user);
void updateUser(AppUser user);
void deleteUser(Long id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<mapper namespace="com.example.app.persistence.UserRepository">
<resultMap id="resultatUtilisateur" type="com.example.app.model.AppUser">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="password" column="password" />
<result property="fullName" column="full_name" />
<result property="createdAt" column="created_at" />
</resultMap>
<sql id="colonnesBase">
id, username, password, full_name, created_at
</sql>
<select id="findAllUsers" resultMap="resultatUtilisateur">
SELECT <include refid="colonnesBase" /> FROM app_user
</select>
<select id="findById" resultMap="resultatUtilisateur" parameterType="long">
SELECT <include refid="colonnesBase" /> FROM app_user WHERE id = #{id}
</select>
<insert id="insertUser" parameterType="com.example.app.model.AppUser" useGeneratedKeys="true" keyProperty="id">
INSERT INTO app_user (username, password, full_name, created_at)
VALUES (#{username}, #{password}, #{fullName}, #{createdAt})
</insert>
<update id="updateUser" parameterType="com.example.app.model.AppUser">
UPDATE app_user
SET username = #{username}, password = #{password}, full_name = #{fullName}, created_at = #{createdAt}
WHERE id = #{id}
</update>
<delete id="deleteUser" parameterType="long">
DELETE FROM app_user WHERE id = #{id}
</delete>
</mapper>
Implémentation de la Couche Métier
Le service fait le pont entre le contrôleur et le dépôt de données. L'annotation @Transactional délègue la gestion des transactions au conteneur Spring.
package com.example.app.business;
import com.example.app.model.AppUser;
import java.util.List;
public interface UserService {
List<AppUser> recupererTousLesUtilisateurs();
}
package com.example.app.business.impl;
import com.example.app.model.AppUser;
import com.example.app.persistence.UserRepository;
import com.example.app.business.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public List<AppUser> recupererTousLesUtilisateurs() {
return userRepository.findAllUsers();
}
}
Contrôleur et Vue
Le contrôleur reçoit les requêtes HTTP, invoque le service métier et retourne une vue. La vue JSP utilise la JSTL pour itérer sur les données.
package com.example.app.controller;
import com.example.app.business.UserService;
import com.example.app.model.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
@Controller
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/utilisateurs")
public ModelAndView listerUtilisateurs() {
ModelAndView modelAndView = new ModelAndView("listeUtilisateurs");
List<AppUser> utilisateurs = userService.recupererTousLesUtilisateurs();
modelAndView.addObject("listeUtilisateurs", utilisateurs);
return modelAndView;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>Répertoire des Utilisateurs</title>
</head>
<body>
<h2>Liste des Utilisateurs Enregistrés</h2>
<table border="1" cellpadding="5" cellspacing="0">
<thead>
<tr>
<th>Identifiant</th>
<th>Nom d'utilisateur</th>
<th>Nom Complet</th>
</tr>
</thead>
<tbody>
<c:forEach var="utilisateur" items="${listeUtilisateurs}">
<tr>
<td>${utilisateur.id}</td>
<td>${utilisateur.username}</td>
<td>${utilisateur.fullName}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
Une fois le projet déployé sur un serveur d'applications comme Apache Tomcat, l'applicatino est accessible via l'URL configurée dans le mapping du contrôleur.