Tutoriel Spring MVC

Dans ce tutoriel Spring MVC, nous allons apprendre comment développer une application web Spring MVC en utilisant Spring Tool Suite. Le framework Spring MVC est largement utilisé pour les applications web Java.

Spring MVC

Tout comme le framework Struts, Spring MVC est également basé sur les technologies Servlet et JSP de Java EE et implémente le modèle ModèleVueContrôleur.

Tutoriel Spring MVC

Nous avons déjà vu comment fonctionne l’injection de dépendances de Spring et dans ce tutoriel, nous allons apprendre comment créer une application web simple en utilisant le framework Spring MVC. Nous pouvons utiliser Eclipse ou IntelliJ IDE pour le développement de projets Spring, mais SpringSource fournit Spring Tool Suite (STS) qui est un IDE basé sur Eclipse et livré avec VMware vFabric tc Server qui est construit sur Apache Tomcat et optimisé pour les applications basées sur Spring. J’utiliserai STS pour le tutoriel Spring MVC et les tutoriels futurs car il facilite la vie du développeur en offrant les fonctionnalités suivantes :

  • Support pour la création d’applications Spring (MVC, Rest, Batch, etc.), idéal pour commencer un projet à partir de zéro. Nous verrons bientôt dans ce tutoriel Spring MVC à quel point il est facile de créer un projet Spring MVC.
  • Offre des fonctionnalités utiles telles que la création de fichiers de configuration Spring, l’analyse des fichiers de configuration et des classes pour fournir des informations utiles à leur sujet.
  • Validation automatique des applications Spring.
  • Support de refactoring pour effectuer facilement des modifications dans le projet, les modifications sont également reflétées dans les fichiers de configuration.
  • Assistance au code non seulement pour les classes mais aussi pour les fichiers de configuration, j’aime beaucoup cette fonctionnalité car la plupart du temps nous avons besoin de savoir ce que nous pouvons utiliser et ses détails.
  • Meilleur support pour la Programmation Orientée Aspect (AOP) grâce à l’intégration d’AspectJ.

En regardant toutes les fonctionnalités que STS offre, j’ai été convaincu et j’ai décidé de l’utiliser pour une application Spring et jusqu’à présent, je suis très satisfait. Téléchargez simplement STS à partir de la Page de téléchargement officielle de STS et installez-le. J’utilise STS 3.4.0.RELEASE qui est basé sur la version Eclipse 4.3.1. Si vous ne voulez pas utiliser STS et que vous souhaitez bénéficier de ses fonctionnalités dans Eclipse existant, vous devez installer son plugin depuis le Marketplace d’Eclipse. Utilisez l’image ci-dessous comme référence et assurez-vous de choisir la bonne version de STS pour l’installation. Le plugin ci-dessous est adapté à Eclipse Kepler. Si vous ne souhaitez pas utiliser le serveur SpringSource, vous pouvez déployer l’application dans tout autre conteneur Java EE tel que Tomcat, JBoss, etc. Pour ce tutoriel, j’utiliserai le serveur fourni avec STS, mais j’ai testé l’application en l’exportant en tant que fichier WAR dans un serveur Tomcat séparé et cela fonctionne très bien. Maintenant que notre environnement de serveur et notre IDE sont prêts, passons à la création de notre premier projet Spring MVC. Les étapes ci-dessous sont valables pour STS ainsi que pour Eclipse avec les plugins STS.

Création d’une application Spring MVC dans STS ou Eclipse

Étape 1: Créez un nouveau projet Spring à partir du menu. Étape 2: Dans la nouvelle fenêtre du projet, donnez le nom « SpringMVCExample » et choisissez le modèle « Projet Spring MVC ». Si vous utilisez ce modèle pour la première fois, STS le téléchargera depuis le site Web de SpringSource. Si vous le souhaitez, vous pouvez ajouter le projet à n’importe quel ensemble de travail. Étape 3: Une fois que le modèle est téléchargé, à l’écran suivant, vous devez fournir le nom du package de niveau supérieur. Ce package sera utilisé comme base pour les composants Spring. Étape 4: Une fois que le projet est créé par le modèle Spring MVC, il ressemblera à l’image ci-dessous. Ne vous inquiétez pas si vous ne voyez pas la classe User.java, les fichiers login.jsp et user.jsp, je les ai ajoutés ultérieurement. Si votre projet n’est pas compilé et que vous voyez des erreurs, exécutez « Maven/Update Project ». Assurez-vous de cocher les options « Force update of Snapshots/Releases », référez-vous à l’image ci-dessous. Dans l’ensemble, le projet ressemble à n’importe quelle autre application Web basée sur Maven avec quelques fichiers de configuration Spring. Maintenant, il est temps d’analyser les différentes parties du projet et de l’étendre un peu.

Dépendances Spring MVC

Notre fichier pom.xml généré ressemble à ceci.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.journaldev</groupId>
	<artifactId>SpringMVCExample</artifactId>
	<name>SpringMVCExample</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>
	<properties>
		<java-version>1.6</java-version>
		<org.springframework-version>4.0.0.RELEASE</org.springframework-version>
		<org.aspectj-version>1.7.4</org.aspectj-version>
		<org.slf4j-version>1.7.5</org.slf4j-version>
	</properties>
	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				 </exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
				
		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>	
		
		<!-- Logging -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.15</version>
			<exclusions>
				<exclusion>
					<groupId>javax.mail</groupId>
					<artifactId>mail</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
			</exclusions>
			<scope>runtime</scope>
		</dependency>

		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
				
		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
	
		<!-- Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>        
	</dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

artifactId sera le servlet-context pour l’application web, vous pouvez le modifier si vous voulez autre chose. Il y a quelques propriétés définies pour les versions de Spring Framework, AspectJ et SLF4j, j’ai remarqué qu’elles ne reflétaient pas les dernières versions, donc je les ai modifiées pour la dernière version stable à ce jour. Les dépendances du projet qui m’intéressent sont les suivantes;

  • spring-context: Dépendance Spring Core. Notez l’exclusion de commons logging au profit de SLF4J.
  • spring-webmvc: Artifact Spring pour le support MVC
  • aspectjrt: Référence API AspectJ
  • SLF4J et Log4j: Pour les besoins de journalisation, Spring est très facile à configurer pour log4j ou Java Logging API grâce à l’intégration de SLF4J.
  • javax.inject – API JSR330 pour l’injection de dépendances

D’autres dépendances ont été ajoutées, telles que Servlet, JSP, JSTL et JUnit API, mais pour une application de départ, nous pouvons les ignorer.

Tutoriel sur Spring MVC – Configuration de Log4j

Le fichier log4j.xml généré ressemble à ceci.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="https://jakarta.apache.org/log4j/">

	<!-- Appenders -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p: %c - %m%n" />
		</layout>
	</appender>
	
	<!-- Application Loggers -->
	<logger name="com.journaldev.spring">
		<level value="info" />
	</logger>
	
	<!-- 3rdparty Loggers -->
	<logger name="org.springframework.core">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.beans">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.context">
		<level value="info" />
	</logger>

	<logger name="org.springframework.web">
		<level value="info" />
	</logger>

	<!-- Root Logger -->
	<root>
		<priority value="warn" />
		<appender-ref ref="console" />
	</root>
	
</log4j:configuration>

Remarquez qu’il affiche tout sur la console, nous pouvons facilement ajouter des appenders pour rediriger les journaux vers des fichiers.

Tutoriel sur Spring MVC – Configuration du descripteur de déploiement

Voyons notre web.xml et analysons-le.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>
	
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

ContextLoaderListener lie le cycle de vie de ApplicationContext au cycle de vie de ServletContext et automatise la création de ApplicationContext. ApplicationContext est l’endroit où se trouvent les beans Spring et nous pouvons fournir sa configuration via le paramètre contextConfigLocation. Le fichier root-context.xml fournit les détails de configuration pour WebApplicationContext. DispatcherServlet est la classe contrôleur pour l’application Spring MVC et toutes les demandes des clients sont gérées par ce servlet. La configuration est chargée à partir du fichier servlet-context.xml.

Tutoriel Spring MVC – Fichiers de configuration

Fichier root-context.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
		
</beans>

Nous pouvons y définir des beans partagés, pour l’instant il n’y a rien dedans. Code servlet-context.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="https://www.springframework.org/schema/beans"
	xmlns:context="https://www.springframework.org/schema/context"
	xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	
	<context:component-scan base-package="com.journaldev.spring" />	
	
</beans:beans>

Voici à quoi ressemble le fichier de configuration standard de Spring, imaginez simplement écrire tout cela vous-même et vous commencerez à aimer l’outil STS. L’élément annotation-driven est utilisé pour informer le servlet Controller que les annotations seront utilisées pour les configurations de bean. L’élément resources définit l’emplacement où nous pouvons placer des fichiers statiques tels que des images, des pages HTML, etc., que nous ne voulons pas obtenir via le framework Spring. InternalResourceViewResolver est le résolveur de vue, nous pouvons spécifier l’emplacement des pages de vue via les propriétés de préfixe et de suffixe. Ainsi, toutes nos pages JSP doivent se trouver dans le répertoire /WEB-INF/views/. L’élément context:component-scan est utilisé pour fournir l’emplacement de base du package pour analyser les classes Controller. Souvenez-vous de la valeur du package de niveau supérieur donnée lors de la création du projet, c’est la même valeur qui est utilisée ici.

Classe Controller Spring MVC

HomeController est créé automatiquement avec la méthode home(), bien que je l’ai étendu un peu en ajoutant les méthodes loginPage() et login().

package com.journaldev.spring;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String loginPage(Locale locale, Model model) {
		return "login";
	}
	
	@RequestMapping(value = "/home", method = RequestMethod.POST)
	public String login(@Validated User user, Model model) {
		model.addAttribute("userName", user.getUserName());
		return "user";
	}
}

L’annotation @Controller est utilisée pour indiquer qu’il s’agit d’une classe de contrôleur web. @RequestMapping est utilisé avec les classes et les méthodes pour rediriger la demande du client vers une méthode de gestionnaire spécifique. Remarquez que les méthodes de gestionnaire renvoient une chaîne de caractères, qui doit être le nom de la page de vue à utiliser comme réponse. Comme vous pouvez le voir, nous avons trois méthodes renvoyant des chaînes de caractères différentes, nous devons donc créer des pages JSP avec le même nom. Remarquez que la méthode login() sera appelée avec la méthode HTTP POST, nous nous attendons donc à recevoir des données de formulaire ici. Nous avons donc une classe de modèle User et elle est marquée pour la validation à l’aide de l’annotation @Validated. Chaque méthode contient un argument de type Model et nous pouvons définir des attributs qui seront utilisés ultérieurement dans les pages de réponse JSP.

Classes de modèle Spring MVC

Les classes de modèle sont utilisées pour contenir les variables de formulaire, notre bean de modèle User ressemble à ceci.

package com.journaldev.spring;

public class User {

	private String userName;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
	
}

A simple java bean with the variable name and its getter and setter methods.

Tutoriel Spring MVC – Pages de vue

Nous avons trois pages JSP comme ci-dessous. Code de la page home.jsp :

<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

<P>  The time on the server is ${serverTime}. </P>
</body>
</html>

Remarquez l’utilisation de l’Expression Language JSP pour récupérer les valeurs des attributs. Code de la page login.jsp :

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login Page</title>
</head>
<body>
<form action="home" method="post">
<input type="text" name="userName"><br>
<input type="submit" value="Login">
</form>
</body>
</html>

A simple JSP page for the user to provide the userName as input. Notice that form variable name is same as User class variable name. Also, form action is “home” and method is “post”. It’s clear that HomeController login() method will handle this request. user.jsp code:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>User Home Page</title>
</head>
<body>
<h3>Hi ${userName}</h3>
</body>
</html>

Page d’accueil simple pour l’utilisateur où le nom d’utilisateur est affiché, remarquez que nous définissons cet attribut dans la méthode de connexion.

Exemple d’application de test Spring MVC

Notre application est prête à être exécutée, il suffit de l’exécuter sur le serveur VMware tc ou tout autre conteneur de servlet de votre choix, vous obtiendrez les pages suivantes en réponse. C’est tout pour le tutoriel Spring MVC, vous pouvez voir à quel point il est facile de créer une application Spring MVC en utilisant les plugins STS. La taille du code est très réduite et la plupart de la configuration est gérée par Spring MVC afin que nous puissions nous concentrer sur la logique métier. Téléchargez le projet Spring MVC d’exemple à partir du lien ci-dessous et amusez-vous avec.

Télécharger le projet Spring MVC

Source:
https://www.digitalocean.com/community/tutorials/spring-mvc-tutorial