Spring Tutoriel MVC

De Get Docs
Aller à :navigation, rechercher

Dans ce didacticiel Spring MVC, nous apprendrons à développer une application Web Spring MVC à l'aide de la suite d'outils Spring. Le framework Spring MVC est largement utilisé pour les applications Web java.

Spring MVC

Tout comme Struts Framework, Spring MVC est également basé sur Java EE Servlet et technologies JSP et implémente Model-View -Modèle de conception Contrôleur.

Spring Tutoriel MVC

Nous avons vu précédemment comment Spring Dependency Injection fonctionne et dans ce didacticiel, nous apprendrons comment créer une application Web simple à l'aide du framework MVC Spring. 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 est livré avec intégré ]VMware vFabric tc Server qui est construit sur le conteneur Tomcat Apache et optimisé pour les applications basées sur Spring. J'utiliserais STS pour Spring tutoriel MVC et d'autres futurs tutoriels car il facilite la vie d'un développeur en fournissant les fonctionnalités suivantes :

  • Prise en charge de la création d'applications squelettiques Spring (MVC, Rest, Batch, etc.), idéale pour démarrer le 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.
  • Fournit des fonctionnalités utiles telles que la création de fichiers de configuration Spring, l'analyse de fichiers de configuration et de classes pour fournir des informations utiles à leur sujet.
  • Validation automatique de la candidature Spring
  • Prise en charge de la refactorisation pour apporter facilement des modifications au 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.
  • Meilleure prise en charge de la programmation orientée aspect (AOP) grâce à l'intégration d'AspectJ.

En regardant toutes les fonctionnalités fournies par STS, j'ai été vendu pour cela et j'ai décidé de l'utiliser pour l'application Spring et jusqu'à présent j'en suis très satisfait. Téléchargez simplement le STS à partir de STS Official Download Page et installez-le. J'utilise STS 3.4.0.RELEASE qui est basé sur la version Eclipse 4.3.1. Si vous ne souhaitez pas utiliser STS et souhaitez obtenir ses fonctionnalités dans Eclipse existant, vous devez installer son plug-in à partir d'Eclipse Marketplace. 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 bon pour Eclipse Kepler. Si vous ne souhaitez pas utiliser le serveur SpringSource, vous pouvez déployer l'application dans n'importe quel autre conteneur EE Java tel que Tomcat, JBoss, etc. Pour ce didacticiel, j'utiliserai le serveur fourni avec STS, mais j'ai testé l'application en l'exportant sous forme de fichier WAR dans un serveur Tomcat séparé et cela fonctionne correctement. Maintenant que notre environnement de serveur et notre IDE sont prêts, procédons à la création de notre premier projet MVC Spring. Les étapes ci-dessous sont valables pour STS ainsi que pour Eclipse avec les plugins STS.

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

Étape 1 : Créer un nouveau projet Spring dans le menu. Étape 2 : Dans la nouvelle fenêtre de projet, nommez « SpringMVCExample » et choisissez le modèle « Spring MVC Project ». Si vous utilisez ce modèle pour la première fois, STS le téléchargera à partir du site Web SpringSource. Si vous le souhaitez, vous pouvez ajouter le projet à n'importe quel ensemble de travail. Étape 3 : Lorsque le modèle est téléchargé, dans l'écran suivant, vous devez fournir le nom du package de niveau supérieur. Ce package sera utilisé comme package de base pour les composants Spring. Étape 4 : Une fois le projet créé par le modèle MVC Spring, il ressemblera à l'image ci-dessous. Ne vous inquiétez pas si vous ne voyez pas les fichiers User.java class, login.jsp et user.jsp, ils ont été ajoutés par moi plus tard. Si votre projet n'est pas compilé et que vous voyez des erreurs, exécutez Maven/Update Project. Assurez-vous de cocher les options "Forcer la mise à jour des instantanés/versions", reportez-vous à l'image ci-dessous. Le projet global ressemble à n'importe quelle autre application Web basée sur Maven avec certains fichiers de configuration Spring. Il est maintenant temps d'analyser les différentes parties des projets et de les étendre un peu.

Spring Dépendances MVC

Notre fichier pom.xml généré ressemble à ci-dessous.

<?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>

artefactId sera le contexte de servlet pour l'application Web, vous pouvez donc le modifier si vous voulez autre chose. Il y a peu de propriétés définies pour les versions Spring Framework, AspectJ et SLF4j, j'ai trouvé qu'elles ne reflétaient pas les dernières versions, donc je les ai changées pour la dernière version stable à ce jour. Les dépendances du projet qui m'intéressent sont;

  • spring-context : Spring Dépendance du noyau. Notez l'exclusion de la journalisation des biens communs en faveur de SLF4J.
  • spring-webmvc : artefact Spring pour la prise en charge de MVC
  • aspectjrt : référence de l'API AspectJ
  • SLF4J et Log4j : à des fins de journalisation, Spring est très facile à configurer pour log4j ou Java API de journalisation grâce à l'intégration de SLF4J.
  • javax.inject - API JSR330 pour l'injection de dépendances

Il existe d'autres dépendances ajoutées, telles que Servlet, JSP, JSTL et JUnit API, mais pour l'application de démarrage, nous pouvons les ignorer.

Spring Tutoriel MVC - Configuration de Log4j

Le fichier log4j.xml généré ressemble à ci-dessous.

<?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>

Notez qu'il imprime tout sur la console, nous pouvons facilement ajouter des appenders pour rediriger la journalisation vers les fichiers.

Spring Tutoriel 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 attache le ApplicationContext cycle de vie à ServletContext cycle de vie et automatiser la création de ApplicationContext. ApplicationContext est l'endroit pour les beans Spring et nous pouvons fournir sa configuration via le paramètre de contexte contextConfigLocation. Le fichier root-context.xml fournit les détails de configuration pour WebApplicationContext. DispatcherServlet est la classe de 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.

Spring Tutoriel 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 définir les beans partagés ici, 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 Spring, imaginez simplement écrire tout cela par vous-même et vous commencerez à aimer l'outil STS. L'élément piloté par les annotations est utilisé pour informer le servlet du contrôleur que les annotations seront utilisées pour les configurations 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 passer par le framework Spring. InternalResourceViewResolver est le résolveur de vue, nous pouvons fournir 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 du package de base pour l'analyse des classes de contrôleur. Rappelez-vous la valeur du package de niveau supérieur donnée au moment de la création du projet, c'est la même valeur qui est utilisée ici.

Spring Classe de contrôleur MVC

HomeController est créé automatiquement avec la méthode home(), bien que je l'ai un peu étendu 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 des classes et des méthodes pour rediriger la demande du client vers une méthode de gestionnaire spécifique. Notez que les méthodes de gestionnaire renvoient String, cela devrait être le nom de la page de vue à utiliser comme réponse. Comme vous pouvez le constater, trois méthodes renvoient des chaînes différentes. Nous devons donc créer des pages JSP portant le même nom. Notez que la méthode login () sera appelée avec la méthode HTTP en tant que POST, nous attendons donc des données de formulaire ici. Nous avons donc la classe de modèle User et elle est marquée pour validation à l'aide de l'annotation @Validated. Chaque méthode contient Model comme argument et nous pouvons définir des attributs à utiliser ultérieurement dans les pages de réponse JSP.

Spring Classes de modèles MVC

Les classes de modèle sont utilisées pour contenir des variables de formulaire, notre modèle utilisateur bean ressemble à ci-dessous.

package com.journaldev.spring;

public class User {

    private String userName;

    public String getUserName() {
        return userName;
    }

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

Un simple java bean avec le nom de la variable et ses méthodes getter et setter.

Spring Tutoriel MVC - Afficher les pages

Nous avons trois pages JSP comme ci-dessous. code 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>

Notez l'utilisation de JSP Expression Language pour obtenir les valeurs d'attribut. code 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>

Une page JSP simple permettant à l'utilisateur de fournir le nom d'utilisateur en entrée. Notez que le nom de la variable de formulaire est le même que le nom de la variable de classe utilisateur. De plus, l'action du formulaire est "home" et la méthode est "post". Il est clair que la méthode login () de HomeController gérera cette demande. code utilisateur.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>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é, notez que nous définissons cet attribut dans la méthode de connexion.

Spring Exemple de test d'application MVC

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

Télécharger Spring Projet MVC