Spring MVC Tutorial

In diesem Spring MVC Tutorial werden wir lernen, wie man eine Spring MVC Webanwendung mit Hilfe von Spring Tool Suite entwickelt. Das Spring MVC Framework wird häufig für Java-Webanwendungen verwendet.

Spring MVC

Genau wie das Struts Framework basiert auch Spring MVC auf Java EE Servlet und JSP-Technologien und implementiert das Model-View-Controller Design Pattern.

Wir haben früher gesehen, wie Spring Dependency Injection funktioniert und in diesem Tutorial werden wir lernen, wie man eine einfache Webanwendung mit dem Spring MVC Framework erstellt. Wir können Eclipse oder IntelliJ IDE für die Entwicklung von Spring-Projekten verwenden, aber SpringSource bietet Spring Tool Suite (STS), eine auf Eclipse basierende IDE, die mit dem integrierten VMware vFabric tc Server kommt, der auf dem Apache Tomcat Container aufgebaut ist und für auf Spring basierende Anwendungen optimiert ist. Ich würde STS für das Spring MVC Tutorial und zukünftige Tutorials verwenden, da es das Leben eines Entwicklers einfacher macht, indem es die folgenden Funktionen bietet:

  • Unterstützung für die Erstellung von Spring-Anwendungen (MVC, Rest, Batch usw.), gut für den Projektstart von Grund auf. Wir werden bald in diesem Spring MVC Tutorial sehen, wie einfach es ist, ein Spring MVC-Projekt zu erstellen.
  • Bietet nützliche Funktionen wie das Erstellen von Spring-Konfigurationsdateien, das Parsen von Konfigurationsdateien und Klassen, um nützliche Informationen über sie zu liefern.
  • Automatische Validierung der Spring-Anwendung
  • Refactoring-Unterstützung, um Projektänderungen leicht durchzuführen, die Änderungen werden auch in den Konfigurationsdateien widergespiegelt.
  • Codeassistenz nicht nur für Klassen, sondern auch für Konfigurationsdateien, diese Funktion mag ich sehr, denn meistens müssen wir wissen, was wir verwenden können und dessen Details.
  • Beste Unterstützung für aspektorientierte Programmierung (AOP) durch die Integration von AspectJ.

Wenn ich mir all die Funktionen ansehe, die STS bietet, war ich überzeugt und habe beschlossen, es für Spring-Anwendungen zu verwenden und bin bis jetzt sehr zufrieden damit. Laden Sie einfach die STS von der offiziellen STS-Downloadseite herunter und installieren Sie sie. Ich verwende STS 3.4.0.RELEASE, das auf Eclipse 4.3.1 basiert.

Wenn Sie STS nicht verwenden möchten und dessen Funktionen in einem bestehenden Eclipse haben möchten, müssen Sie dessen Plugin aus dem Eclipse Marketplace installieren. Verwenden Sie das folgende Bild als Referenz und stellen Sie sicher, dass Sie die richtige STS-Version für die Installation auswählen. Das untenstehende Plugin ist gut für Eclipse Kepler.

Spring Tool Suite Eclipse

Wenn Sie den SpringSource-Server nicht verwenden möchten, können Sie die Anwendung in einem anderen Java EE-Container wie Tomcat, JBoss usw. bereitstellen. Für dieses Tutorial werde ich den Server verwenden, der mit STS geliefert wird, aber ich habe die Anwendung getestet, indem ich sie als WAR-Datei in einen separaten Tomcat-Server exportiert habe und sie funktioniert einwandfrei. Jetzt, da unsere Serverumgebung und IDE bereit sind, lasst uns unser erstes Spring MVC-Projekt erstellen. Die folgenden Schritte sind sowohl für STS als auch für Eclipse mit STS-Plugins gültig.

Erstellung einer Spring MVC-Anwendung in STS oder Eclipse

Schritt 1: Erstellen Sie ein neues Spring-Projekt aus dem Menü.

Spring Project New

Schritt 2: Geben Sie im neuen Projekt-Fenster den Namen „SpringMVCExample“ ein und wählen Sie die Vorlage „Spring MVC Project“. Wenn Sie diese Vorlage zum ersten Mal verwenden, wird STS sie von der SpringSource-Website herunterladen. Wenn Sie möchten, können Sie das Projekt einem Arbeitsset hinzufügen.

Spring New MVC Project Template
Spring MVC Template Download

Schritt 3: Wenn die Vorlage heruntergeladen ist, müssen Sie im nächsten Bildschirm den Namen des obersten Pakets angeben. Dieses Paket wird als Basis-Paket für Spring-Komponenten verwendet.

Spring MVC Source Package

Schritt 4: Sobald das Projekt mit der Spring MVC-Vorlage erstellt wurde, sieht es wie im untenstehenden Bild aus.

Spring MVC STS Project

Machen Sie sich keine Sorgen, wenn Sie die User.java-Klasse, login.jsp und user.jsp Dateien nicht sehen, diese wurden später von mir hinzugefügt. Wenn Ihr Projekt nicht kompiliert ist und Sie einige Fehler sehen, führen Sie Maven/Update Project aus. Stellen Sie sicher, dass Sie die Option „Force update of Snapshots/Releases“ überprüfen, siehe untenstehendes Bild.

Maven Force Update Projects

Das gesamte Projekt sieht aus wie jede andere Maven-basierte Webanwendung mit einigen Spring-Konfigurationsdateien. Jetzt ist es an der Zeit, die verschiedenen Teile des Projekts zu analysieren und ein wenig zu erweitern.

Spring MVC Abhängigkeiten

Unsere generierte pom.xml-Datei sieht wie folgt aus.

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

Unsere generierte pom.xml-Datei sieht wie folgt aus. Die artifactId wird der servlet-context für die Webanwendung sein, also können Sie diese ändern, wenn Sie etwas anderes möchten. Es gibt einige Eigenschaften, die für Spring Framework, AspectJ und SLF4j-Versionen definiert sind. Ich habe festgestellt, dass sie nicht die neuesten Versionen widerspiegeln, also habe ich sie auf die neueste stabile Version von heute geändert. Die Projektabhängigkeiten, die mich interessieren, sind;

  • spring-context: Spring Core-Abhängigkeit. Beachten Sie den Ausschluss des Commons Logging zugunsten von SLF4J.
  • spring-webmvc: Spring-Artefakt für MVC-Unterstützung
  • aspectjrt: AspectJ API-Referenz
  • SLF4J und Log4j: Für Logging-Zwecke ist Spring sehr leicht für log4j oder Java Logging API zu konfigurieren aufgrund der SLF4J-Integration.
  • javax.inject – JSR330 API für Dependency Injection

Es gibt einige andere Abhängigkeiten, die hinzugefügt wurden, wie Servlet, JSP, JSTL und JUnit API, aber für eine Starter-Anwendung können wir diese übersehen.

Spring MVC Tutorial – Log4j-Konfiguration

Die generierte log4j.xml-Datei sieht wie folgt aus. Beachten Sie, dass alles auf die Konsole gedruckt wird, wir können leicht Appender hinzufügen, um das Logging in Dateien umzuleiten.

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

Spring MVC Tutorial – Konfiguration des Deployment Descriptors

Lassen Sie uns unsere web.xml anschauen und analysieren.

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

Der ContextLoaderListener verknüpft den Lebenszyklus des ApplicationContext mit dem Lebenszyklus des ServletContext und automatisiert die Erstellung des ApplicationContext. ApplicationContext ist der Ort für Spring-Beans und wir können seine Konfiguration über den Kontextparameter contextConfigLocation bereitstellen. Die Datei root-context.xml enthält die Konfigurationsdetails für den WebApplicationContext. DispatcherServlet ist die Controller-Klasse für die Spring MVC-Anwendung und alle Client-Anfragen werden von diesem Servlet bearbeitet. Die Konfiguration wird aus der Datei servlet-context.xml geladen.

Spring MVC Tutorial – Konfigurationsdateien

root-context.xml-Datei:

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

Wir können hier gemeinsam genutzte Beans definieren, momentan ist jedoch nichts darin enthalten.

servlet-context.xml Code:

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

So sieht die Standard-Spring-Konfigurationsdatei aus, stellen Sie sich vor, all dies selbst zu schreiben, und Sie werden anfangen, das STS-Tool zu mögen. Das annotation-driven-Element wird verwendet, um dem Controller-Servlet mitzuteilen, dass Annotationen für die Bean-Konfigurationen verwendet werden. Das resources-Element definiert den Ort, an dem wir statische Dateien wie Bilder, HTML-Seiten usw. ablegen können, die wir nicht durch das Spring-Framework leiten möchten. InternalResourceViewResolver ist der View-Resolver, wir können den Ort der View-Seiten über die Eigenschaften prefix und suffix angeben. Daher sollten alle unsere JSP-Seiten im Verzeichnis /WEB-INF/views/ liegen. Das Element context:component-scan wird verwendet, um den Ort des Basis-Pakets für das Scannen von Controller-Klassen anzugeben. Erinnern Sie sich an den Wert des obersten Pakets, das zum Zeitpunkt der Projekterstellung angegeben wurde, es ist derselbe Wert, der hier verwendet wird.

Spring MVC Controller-Klasse

HomeController wird automatisch mit der Methode home() erstellt, obwohl ich sie ein wenig erweitert habe, indem ich die Methoden loginPage() und login() hinzugefügt habe.

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";
    }
}

Die @Controller-Annotation wird verwendet, um anzuzeigen, dass es sich um eine Web-Controller-Klasse handelt. @RequestMapping wird bei Klassen und Methoden verwendet, um die Client-Anfrage an eine spezifische Handler-Methode umzuleiten. Beachten Sie, dass die Handler-Methoden String zurückgeben, dies sollte der Name der View-Seite sein, die als Antwort verwendet wird. Wie Sie sehen können, haben wir drei Methoden, die verschiedene Strings zurückgeben, daher müssen wir JSP-Seiten mit demselben Namen erstellen. Beachten Sie, dass die login()-Methode mit der HTTP-Methode POST aufgerufen wird, daher erwarten wir hier einige Formulardaten. Daher haben wir eine User-Model-Klasse und sie ist zur Validierung mit der @Validated-Annotation markiert. Jede Methode enthält Model als Argument und wir können Attribute festlegen, die später in den JSP-Antwortseiten verwendet werden.

Spring MVC Model-Klassen

Model-Klassen werden verwendet, um Formularvariablen zu halten, unser User-Model-Bean sieht wie folgt aus.

package com.journaldev.spring;

public class User {

    private String userName;

    public String getUserName() {
        return userName;
    }

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

Ein einfaches Java-Bean mit dem Variablennamen und seinen Getter- und Setter-Methoden.

Spring MVC Tutorial – Ansichtsseiten

home.jsp Code:

<%@ 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>

Beachten Sie die Verwendung der JSP Expression Language, um die Attributwerte zu erhalten.

login.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>Login Page</title>
</head>
<body>
<form action="home" method="post">
<input type="text" name="userName"><br>
<input type="submit" value="Login">
</form>
</body>
</html>

Eine einfache JSP-Seite, auf der der Benutzer den Benutzernamen als Eingabe angeben kann. Beachten Sie, dass der Name der Formularvariablen gleich dem Variablennamen der User-Klasse ist. Außerdem ist die Formularaktion „home“ und die Methode „post“. Es ist klar, dass die login()-Methode des HomeController diese Anfrage bearbeiten wird.

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>

Eine einfache Startseite für den Benutzer, auf der der Benutzername angezeigt wird. Beachten Sie, dass wir dieses Attribut in der Login-Methode setzen.

Spring MVC Beispielanwendung Testen

Unsere Anwendung ist bereit zur Ausführung, führen Sie sie einfach auf dem VMware tc Server oder einem anderen Servlet-Container Ihrer Wahl aus, Sie werden die untenstehenden Seiten als Antwort erhalten.



Das ist es für das Spring MVC Tutorial, Sie können sehen, wie einfach es ist, eine Spring MVC-Anwendung mit STS-Plugins zu erstellen. Der Codeumfang ist sehr gering und der Großteil der Konfiguration wird von Spring MVC gehandhabt, sodass wir uns auf die Geschäftslogik konzentrieren können.

Kostenlosen Account erstellen

Registrieren Sie sich jetzt und erhalten Sie Zugang zu unseren Cloud Produkten.

Das könnte Sie auch interessieren: