Ce projet présente une application web complète pour la gestion opérationnelle d’un établissement caféiné, conçue selon les bonnes pratiques du développement Java moderne. L’architecture repose sur le stack SSM (Spring, Spring MVC, MyBatis), avec une couche présentation basée sur JSP, déployée sur un serveur Tomcat et alimentée par une base de données relationnelle MySQL.
Architecture technique
- Couche présentation : Pages JSP dynamiques avec intégration de balises JSTL et expression language (EL) pour affichage conditionnel, itération et liaison de données.
- Couche métier : Spring gère la configuration, l’injection de dépendances et les transactions ; Spring MVC assure le routage des requêtes via des contrôleurs annotés (
@Controller,@RequestMapping). - Couche d’accès aux données : MyBatis permet une abstraction fluide des opérations SQL grâce à des mapppers XML ou annotations, avec support natif des requêtes paramétrées et des résultats paginés.
- Outils de construction : Maven standardise la gestion des dépendances et le cycle de build via des profils spécifiques (développement, production).
Fonctionnalités clés implémentées
Le système couvre plusieurs domaines critiques de la gestion caféière :
- Gestion des commandes en temps réel (création, suivi, annulation)
- Système de réservation en ligne avec validation de disponibilité horaire
- Module fidélité avec niveaux de membre, points accumulés et récompenses personnalisables
- Tableau de bord administrateur incluant des statistiques de ventes quotidiennes et rapports sur les produits les plus populaires
- Gestion des stocks avec alertes automatiques lors de seuils critiques
- Interface caisse simplifiée avec impression de ticket et génération de facture PDF
Exemple de logique métier refactorisée
Voici une version modernisée du service utilisateur, utilisant des fonctionnalités avancées de MyBatis Plus et une approche orientée domaine :
@Service
public class StaffAccountService {
private final StaffMapper staffMapper;
private final PasswordEncoder passwordEncoder;
public StaffAccountService(StaffMapper staffMapper, PasswordEncoder passwordEncoder) {
this.staffMapper = staffMapper;
this.passwordEncoder = passwordEncoder;
}
public PageResult<StaffProfile> findActiveStaff(PageRequest pageRequest, String searchKeyword) {
LambdaQueryWrapper<StaffEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(StaffEntity::getStatus, Status.ACTIVE);
if (StringUtils.isNotBlank(searchKeyword)) {
wrapper.and(q -> q.like(StaffEntity::getFirstName, searchKeyword)
.or().like(StaffEntity::getLastName, searchKeyword));
}
Page<StaffEntity> page = staffMapper.selectPage(pageRequest.toPage(), wrapper);
List<StaffProfile> profiles = page.getRecords().stream()
.map(this::toProfile)
.collect(Collectors.toList());
return new PageResult<>(profiles, page.getTotal(), page.getCurrent(), page.getSize());
}
private StaffProfile toProfile(StaffEntity entity) {
return StaffProfile.builder()
.id(entity.getId())
.fullName(entity.getFirstName() + " " + entity.getLastName())
.role(entity.getRole().getDisplayName())
.lastLogin(entity.getLastLoginTime())
.build();
}
}
// Classe utilitaire sécurisée pour hachage de mot de passe
public class SecureHasher {
private static final String SALT_PREFIX = "cafe-2025-";
public static String hashPassword(String rawPassword) {
String salted = SALT_PREFIX + rawPassword;
return DigestUtils.sha256Hex(salted);
}
}
Configuratino de déploiement
Le fichier application.yml centralise les paramètres environnementaux :
spring:
datasource:
url: jdbc:mysql://localhost:3306/cafe_management?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
username: cafe_app
password: secure_password_123
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
server:
port: 8080
servlet:
context-path: /cafe
Tests fonctionnels recommandés
Pour garantir la robustesse du système, les scénarios suivants sont essentiels :
- Validation de la cohérence entre stock disponible et quantité commandée (rollback transactionnel en cas de rupture)
- Vérification de l’expiration automatique des réservations non confirmées après 15 minutes
- Test de sécurité : injection SQL bloquée, XSS filtré sur les champs de saisie client
- Chargement simultané de 50 utilisateurs simulés pour mesurer la latence moyenne des requêtes critiques