In deze Spring MVC Tutorial zullen we leren hoe we een Spring MVC-webtoepassing kunnen ontwikkelen met behulp van Spring Tool Suite. Het Spring MVC-framework wordt veel gebruikt voor Java-webtoepassingen.
Spring MVC
Net als het Struts Framework is Spring MVC ook gebaseerd op Java EE Servlet- en JSP-technologieën en implementeert het het Model–View–Controller-ontwerppatroon.
Spring MVC Tutorial
We hebben eerder gezien hoe Spring Dependency Injection werkt en in deze tutorial zullen we leren hoe we een eenvoudige webtoepassing kunnen maken met behulp van het Spring MVC-framework. We kunnen Eclipse of IntelliJ IDE gebruiken voor de ontwikkeling van Spring-projecten, maar SpringSource biedt Spring Tool Suite (STS) aan, dat een IDE is gebaseerd op Eclipse en wordt geleverd met een ingebouwde VMware vFabric tc Server die is gebouwd op de Apache Tomcat-container en geoptimaliseerd is voor Spring-gebaseerde applicaties. Ik zou STS gebruiken voor Spring MVC-tutorial en andere toekomstige tutorials omdat het het leven van een ontwikkelaar gemakkelijker maakt door de volgende functies te bieden:
- Ondersteuning voor het maken van skeletachtige Spring-toepassingen (MVC, Rest, Batch, enz.), ideaal om het project vanaf het begin te starten. We zullen binnenkort in deze Spring MVC-tutorial zien hoe eenvoudig het is om een Spring MVC-project te maken.
- Biedt handige functies zoals het maken van Spring-configuratiebestanden, het parseren van configuratiebestanden en klassen om nuttige informatie erover te verstrekken.
- Automatische validatie van Spring-toepassing.
- Ondersteuning voor refactoring om gemakkelijk projectwijzigingen aan te brengen, de wijzigingen worden ook doorgevoerd in configuratiebestanden.
- Code-assistentie niet alleen voor klassen maar ook voor configuratiebestanden, ik vind deze functie erg handig omdat we meestal moeten weten wat we kunnen gebruiken en de details ervan.
- De beste ondersteuning voor Aspect Oriented Programming (AOP) door de integratie van AspectJ.
Kijkend naar alle functies die STS biedt, was ik overtuigd en besloot ik het te gebruiken voor mijn Spring-toepassing en tot nu toe ben ik er erg blij mee. Download gewoon de STS van de STS Officiële Download Pagina en installeer het. Ik gebruik STS 3.4.0.RELEASE dat gebaseerd is op Eclipse 4.3.1 release. Als je STS niet wilt gebruiken en de faciliteiten ervan in een bestaande Eclipse wilt krijgen, dan moet je de plugin ervan installeren vanuit de Eclipse Marketplace. Gebruik onderstaande afbeelding als referentie en zorg ervoor dat je de juiste STS-versie kiest voor installatie. De onderstaande plugin is goed voor Eclipse Kepler.
Als je geen SpringSource-server wilt gebruiken, kun je de toepassing implementeren in een andere Java EE-container zoals Tomcat, JBoss, enz. Voor deze tutorial zal ik de server gebruiken die wordt meegeleverd met STS, maar ik heb de toepassing getest door deze als WAR-bestand te exporteren naar een aparte Tomcat-server en het werkt prima. Nu onze serveromgeving en IDE gereed zijn, laten we doorgaan met het maken van ons eerste Spring MVC-project. De onderstaande stappen zijn geldig voor zowel STS als Eclipse met STS-plugins.
Het maken van een Spring MVC-toepassing in STS of Eclipse
Stap 1: Maak een nieuw Spring-project vanuit het menu. Stap 2: Geef in het nieuwe projectvenster de naam op als “SpringMVCExample” en kies het sjabloon als “Spring MVC Project”. Als je dit sjabloon voor de eerste keer gebruikt, zal STS het downloaden vanaf de SpringSource-website. Als je wilt, kun je het project toevoegen aan een werkset.
Stap 3: Wanneer het sjabloon is gedownload, moet je op het volgende scherm de naam van het pakket op het hoogste niveau opgeven. Dit pakket wordt gebruikt als het basispakket voor Spring-componenten.
Stap 4: Zodra het project is aangemaakt door het Spring MVC-sjabloon, ziet het eruit zoals hieronder afgebeeld.
Maak je geen zorgen als je de klasse User.java, login.jsp en user.jsp niet ziet, die heb ik later toegevoegd. Als je project niet is gecompileerd en je ziet fouten, voer dan Maven/Update Project uit. Zorg ervoor dat je de opties “Force update of Snapshots/Releases” controleert, zie onderstaande afbeelding.
Over het algemeen ziet het project eruit als elke andere op Maven gebaseerde webtoepassing met enkele Spring-configuratiebestanden. Nu is het tijd om de verschillende delen van de projecten te analyseren en deze een beetje uit te breiden.
Voorjaar MVC Afhankelijkheden
Ons gegenereerde pom.xml-bestand ziet er als volgt uit.
<?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 zal de servlet-context zijn voor de webtoepassing, dus je kunt het wijzigen als je iets anders wilt. Er zijn enkele eigenschappen gedefinieerd voor Spring Framework, AspectJ en SLF4j-versies, ik ontdekte dat ze niet de nieuwste versies weerspiegelden, dus heb ik ze gewijzigd naar de nieuwste stabiele versie van vandaag. De projectafhankelijkheden waar ik in geïnteresseerd ben, zijn;
- spring-context: Spring Core-afhankelijkheid. Let op de uitsluiting van commons logging ten gunste van SLF4J.
- spring-webmvc: Spring-artefact voor MVC-ondersteuning
- aspectjrt: AspectJ API-referentie
- SLF4J en Log4j: Voor logging-doeleinden is Spring erg gemakkelijk te configureren voor log4j of Java Logging API vanwege de integratie met SLF4J.
- javax.inject – JSR330 API voor afhankelijkheidsinjectie
Er zijn nog enkele andere afhankelijkheden toegevoegd, zoals Servlet, JSP, JSTL en JUnit API, maar voor een startersapplicatie kunnen we ze negeren.
Spring MVC Tutorial – Log4j Configuratie
Het gegenereerde log4j.xml-bestand ziet er als volgt uit.
<?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>
Merk op dat alles naar de console wordt afgedrukt, we kunnen eenvoudig appenders toevoegen om logging naar bestanden om te leiden.
Spring MVC Tutorial – Inzetbeschrijving Configuratie
Laten we onze web.xml bekijken en analyseren.
<?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
koppelt de levenscyclus van de ApplicationContext
aan de levenscyclus van de ServletContext
en automatiseert de creatie van de ApplicationContext
. ApplicationContext
is de plaats voor Spring-beans en we kunnen de configuratie ervan verstrekken via de contextparameter contextConfigLocation. Het bestand root-context.xml bevat de configuratiedetails voor WebApplicationContext. DispatcherServlet
is de controllerklasse voor de Spring MVC-toepassing en alle clientverzoeken worden afgehandeld door deze servlet. De configuratie wordt geladen vanuit het bestand servlet-context.xml.
Spring MVC Zelfstudie – Configuratiebestanden
root-context.xml bestand:
<?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>
Hier kunnen we gedeelde beans definiëren, op dit moment staat er niets in. 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>
Dit is hoe het standaard Spring-configuratiebestand eruitziet, stel je voor dat je dit allemaal zelf zou moeten schrijven en je zult de STS-tool gaan waarderen. Het annotation-driven-element wordt gebruikt om de Controller-servlet te laten weten dat annotaties zullen worden gebruikt voor bean-configuraties. Het resources-element definieert de locatie waar we statische bestanden zoals afbeeldingen, HTML-pagina’s, enzovoort kunnen plaatsen die we niet via het Spring-framework willen laten verlopen. InternalResourceViewResolver
is de view-resolver, we kunnen de locatie van de view-pagina’s opgeven via de prefix- en suffix-eigenschappen. Dus al onze JSP-pagina’s moeten zich bevinden in de /WEB-INF/views/ map. Het context:component-scan-element wordt gebruikt om de basispakketlocatie te bieden voor het scannen van Controller-klassen. Onthoud de waarde van het top-level pakket die is opgegeven bij het maken van het project, dezelfde waarde wordt hier gebruikt.
Spring MVC Controller Klasse
HomeController wordt automatisch aangemaakt met de home() methode, hoewel ik het een beetje heb uitgebreid door loginPage() en login() methodes toe te voegen.
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";
}
}
@Controller-annotatie wordt gebruikt om aan te geven dat dit een webcontrollerklasse is. @RequestMapping wordt gebruikt bij klassen en methoden om het clientverzoek om te leiden naar een specifieke verwerkingsmethode. Let op dat de verwerkingsmethoden een String retourneren, dit moet de naam zijn van de te gebruiken weergavepagina als reactie. Zoals je kunt zien, hebben we drie methoden die verschillende strings retourneren, dus moeten we JSP-pagina’s maken met dezelfde naam. Merk op dat de login() methode wordt aangeroepen met de HTTP-methode POST, dus we verwachten hier wat formuliergegevens. Daarom hebben we een User-modelklasse en deze is gemarkeerd voor validatie met de annotatie @Validated. Elke methode bevat Model als argument en we kunnen attributen instellen die later worden gebruikt in de JSP-reactiepagina’s.
Spring MVC Modelklassen
Modelklassen worden gebruikt om formuliervariabelen vast te houden, ons User-modelbean ziet er als volgt uit.
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.
Spring MVC Tutorial – Weergavepagina’s
We hebben drie JSP-pagina’s zoals hieronder. Code van 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>
Let op het gebruik van JSP Expression Language om de attribuutwaarden op te halen. Code van 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>
Eenvoudige startpagina voor de gebruiker waar de gebruikersnaam wordt weergegeven, let op dat we deze attribuutwaarde instellen in de inlogmethode.
Spring MVC Voorbeeldapplicatie Testen
Onze applicatie is klaar voor uitvoering, voer deze gewoon uit op de VMware tc Server of een andere servletcontainer naar keuze, je zult onderstaande pagina’s als reactie krijgen.
Dat is alles voor de Spring MVC Tutorial, je kunt zien hoe eenvoudig het is om een Spring MVC applicatie te maken met behulp van STS-plugins. De codegrootte is erg klein en het grootste deel van de configuratie wordt afgehandeld door Spring MVC, zodat we ons kunnen concentreren op de bedrijfslogica. Download het voorbeeld Spring MVC-project via onderstaande link en probeer ermee te spelen.
Source:
https://www.digitalocean.com/community/tutorials/spring-mvc-tutorial