Поиск по сайту:

Учебник Spring MVC


В этом учебном пособии по Spring MVC мы узнаем, как разрабатывать веб-приложение Spring MVC с использованием Spring Tool Suite. Фреймворк Spring MVC широко используется для веб-приложений Java.

Весенний МВК

Учебник Spring MVC

Ранее мы видели, как работает Spring Dependency Injection, и в этом руководстве мы узнаем, как создать простое веб-приложение с использованием среды Spring MVC. Мы можем использовать Eclipse или IntelliJ IDE для разработки проектов Spring, но SpringSource предоставляет Spring Tool Suite (STS), который представляет собой IDE на основе Eclipse и поставляется со встроенным сервером VMware vFabric tc, созданным поверх контейнера Apache Tomcat и оптимизированным. для приложений на основе Spring. Я бы использовал учебник STS для Spring MVC и другие будущие руководства, потому что он упрощает жизнь разработчика, предоставляя следующие функции:

  • Поддержка создания каркасных приложений Spring (MVC, Rest, Batch и т. д.), что удобно для запуска проекта с нуля. В этом весеннем руководстве по MVC мы скоро увидим, как легко создать проект Spring MVC.
  • Предоставляет полезные функции, такие как создание файлов конфигурации Spring, синтаксический анализ файлов конфигурации и классов для предоставления полезной информации о них.
  • Автоматическая проверка приложения Spring
  • Поддержка рефакторинга для легкого внесения изменений в проект, изменения также отражаются в файлах конфигурации.
  • Помощник по коду не только для классов, но и для файлов конфигурации. Мне очень нравится эта функция, потому что в большинстве случаев нам нужно знать, что мы можем использовать, и его детали.
  • Лучшая поддержка аспектно-ориентированного программирования (АОП) благодаря интеграции AspectJ.

Создание приложения Spring MVC в STS или Eclipse

Весенние зависимости MVC

Наш сгенерированный файл pom.xml выглядит так, как показано ниже.

<?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 будет контекстом сервлета для веб-приложения, поэтому вы можете изменить его, если хотите что-то еще. Для версий Spring Framework, AspectJ и SLF4j определено несколько свойств, я обнаружил, что они не отражают последние версии, поэтому я изменил их на последнюю стабильную версию на сегодняшний день. Интересующие меня зависимости проекта:

  • spring-context: зависимость Spring Core. Обратите внимание на исключение регистрации общих ресурсов в пользу SLF4J.
  • spring-webmvc: артефакт Spring для поддержки MVC
  • aspectjrt: справочник по API AspectJ
  • SLF4J и Log4j. Для ведения журналов Spring очень легко настроить для log4j или Java Logging API благодаря интеграции SLF4J.
  • javax.inject — API JSR330 для внедрения зависимостей

Добавлены некоторые другие зависимости, такие как Servlet, JSP, JSTL и JUnit API, но для начального приложения мы можем их пропустить.

Учебное пособие по Spring MVC — конфигурация Log4j

Сгенерированный файл log4j.xml выглядит следующим образом.

<?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 — конфигурация дескриптора развертывания

Давайте посмотрим наш web.xml и проанализируем его.

<?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 связывает жизненный цикл ApplicationContext с жизненным циклом ServletContext и автоматизирует создание ApplicationContext. ApplicationContext — это место для компонентов Spring, и мы можем указать его конфигурацию с помощью параметра контекста contextConfigLocation. В файле root-context.xml содержатся сведения о конфигурации для WebApplicationContext. DispatcherServlet — это класс контроллера для приложения Spring MVC, и все клиентские запросы обрабатываются этим сервлетом. Конфигурация загружается из файла servlet-context.xml.

Учебное пособие по Spring MVC — Файлы конфигурации

файл 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>

Мы можем определить общие компоненты здесь, на данный момент в нем ничего нет. код 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>

Вот так выглядит стандартный конфигурационный файл Spring, просто представьте, что вы пишете все это самостоятельно, и вам начнет нравиться инструмент STS. Элемент annotation-driven используется, чтобы сообщить сервлету Controller, что аннотации будут использоваться для конфигураций bean-компонентов. Элемент resources определяет место, куда мы можем поместить статические файлы, такие как изображения, HTML-страницы и т. д., которые мы не хотим получать через среду Spring. InternalResourceViewResolver — это преобразователь представления, мы можем предоставить расположение страниц представления с помощью свойств префикса и суффикса. Таким образом, все наши JSP-страницы должны находиться в каталоге /WEB-INF/views/. Элемент context:component-scan используется для указания местоположения базового пакета для сканирования классов контроллера. Помните значение пакета верхнего уровня, заданное во время создания проекта, это же значение используется здесь.

Spring Класс контроллера MVC

HomeController создается автоматически с помощью метода home(), хотя я немного расширил его, добавив методы loginPage() и 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";
	}
}

@Проверенная аннотация. Каждый метод содержит модель в качестве аргумента, и мы можем установить атрибуты, которые будут позже использоваться на страницах ответов JSP.

Классы моделей Spring MVC

Классы моделей используются для хранения переменных формы, наш bean-компонент модели User выглядит так, как показано ниже.

package com.journaldev.spring;

public class User {

	private String userName;

	public String getUserName() {
		return userName;
	}

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

Простой Java-бин с именем переменной и ее методами получения и установки.

Учебное пособие по Spring MVC — просмотр страниц

У нас есть три страницы JSP, как показано ниже. код 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>

Обратите внимание на использование языка выражений JSP для получения значений атрибутов. код 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>

Простая JSP-страница, на которой пользователь может указать userName в качестве входных данных. Обратите внимание, что имя переменной формы совпадает с именем переменной класса User. Кроме того, действие формы — это «дом», а метод — «пост». Понятно, что этот запрос обработает метод login() HomeController. код user.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>

Простая домашняя страница для пользователя, на которой отображается имя пользователя, обратите внимание, что мы устанавливаем этот атрибут в методе входа в систему.

Пример тестирования приложения Spring MVC

Скачать проект Spring MVC