В этом учебнике о Spring MVC мы узнаем, как разрабатывать веб-приложение Spring MVC с использованием Spring Tool Suite. Фреймворк Spring MVC широко используется для java-веб-приложений.
Как и фреймворк Struts, Spring MVC также основан на технологиях Java EE Servlet и JSP и реализует шаблон проектирования Model-View-Controller.
Мы ранее видели, как работает внедрение зависимостей в Spring, и в этом уроке мы узнаем, как создать простое веб-приложение с использованием фреймворка Spring MVC. Мы можем использовать среду разработки Eclipse или IntelliJ для разработки проектов Spring, но SpringSource предоставляет Spring Tool Suite (STS), которая является IDE на основе Eclipse и поставляется с встроенным VMware vFabric tc Server, построенным на основе контейнера Apache Tomcat и оптимизированным для приложений, основанных на Spring. Я буду использовать STS для учебника по Spring MVC и будущих уроков, потому что это упрощает жизнь разработчика, предоставляя следующие функции:
- Поддержка создания каркасов Spring-приложений (MVC, Rest, Batch и др.), отлично подходит для начала проекта с нуля. Мы вскоре увидим в этом уроке по Spring MVC, насколько легко создать проект Spring MVC.
- Предоставляет полезные функции, такие как создание файлов конфигурации Spring, анализ файлов конфигурации и классов для предоставления полезной информации о них.
- Автоматическая валидация Spring-приложения
- Поддержка рефакторинга для легкости внесения изменений в проект, изменения отражаются и в файлах конфигурации.
- Подсказка кода не только для классов, но и для файлов конфигурации. Мне очень нравится эта функция, потому что большую часть времени нам нужно знать, что мы можем использовать и его подробности.
- Лучшая поддержка аспектно-ориентированного программирования (AOP) через интеграцию с AspectJ.
Просматривая все функции, которые предоставляет STS, я убедился в его преимуществах и решил использовать его для приложения Spring, и до сих пор я очень доволен им. Просто скачайте STS с Официальной страницы загрузки STS и установите его. Я использую STS 3.4.0.RELEASE, основанный на выпуске Eclipse 4.3.1. Если вы не хотите использовать STS и хотите получить его возможности в существующем Eclipse, вам нужно установить его плагин из Eclipse Marketplace. Используйте нижнее изображение в качестве справки и убедитесь, что выбрана правильная версия STS для установки. Указанный плагин подходит для Eclipse Kepler.
Если вы не хотите использовать сервер SpringSource, вы можете развернуть приложение в любом другом контейнере Java EE, таком как Tomcat, JBoss и т. д. Для этого руководства я буду использовать сервер, поставляемый с STS, но я протестировал приложение, экспортировав его как файл WAR в отдельный сервер Tomcat, и оно работает отлично. Теперь, когда наше серверное окружение и IDE готовы, приступим к созданию нашего первого проекта Spring MVC. Приведенные ниже шаги действительны как для STS, так и для Eclipse с плагинами STS.
Создание приложения Spring MVC в STS или Eclipse
Шаг 1: Создайте новый проект Spring из меню. Шаг 2: В окне нового проекта укажите имя “SpringMVCExample” и выберите шаблон “Spring MVC Project”. Если вы используете этот шаблон впервые, STS загрузит его с веб-сайта SpringSource. При желании вы можете добавить проект в любой рабочий набор.
Шаг 3: После загрузки шаблона на следующем экране вам нужно указать имя пакета верхнего уровня. Этот пакет будет использоваться как базовый пакет для компонентов Spring.
Шаг 4: После создания проекта с помощью шаблона Spring MVC он будет выглядеть как на изображении ниже.
Не беспокойтесь, если вы не видите класс User.java, файлы login.jsp и user.jsp, они были добавлены мной позже. Если ваш проект не скомпилирован и вы видите ошибки, выполните Maven/Update Project. Обязательно установите флажок “Force update of Snapshots/Releases”, см. изображение ниже.
В целом, проект выглядит так же, как любое другое веб-приложение на основе Maven с некоторыми файлами конфигурации Spring. Теперь пришло время проанализировать различные части проекта и немного их расширить.
Зависимости Spring 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 будет servlet-context для веб-приложения, так что вы можете изменить его, если хотите что-то другое. Определено несколько свойств для версий Spring Framework, AspectJ и SLF4j, я обнаружил, что они не отражают последние версии, поэтому я изменил их на последнюю стабильную версию на сегодняшний день. Зависимости проекта, которые меня интересуют, включают;
- spring-context: Зависимость Spring Core. Обратите внимание на исключение commons logging в пользу SLF4J.
- spring-webmvc: Артефакт Spring для поддержки MVC
- aspectjrt: Ссылка на API AspectJ
- SLF4J и Log4j: Для целей ведения журнала, Spring очень легко настроить для log4j или Java Logging API благодаря интеграции SLF4J.
- javax.inject – JSR330 API для внедрения зависимостей
Есть еще некоторые другие добавленные зависимости, такие как Servlet, JSP, JSTL и API JUnit, но для начального приложения мы можем их пропустить.
Учебное пособие по 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 используется, чтобы дать контроллеру сервлета знать, что аннотации будут использоваться для конфигурации бинов. Элемент resources определяет местоположение, где мы можем поместить статические файлы, такие как изображения, HTML-страницы и т. д., которые мы не хотим получать через фреймворк Spring. InternalResourceViewResolver
– это резольвер представлений, мы можем указать местоположение страниц представлений через свойства prefix и suffix. Так что все наши страницы 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";
}
}
Аннотация @Controller используется для указания того, что это класс веб-контроллера. @RequestMapping используется с классами и методами для перенаправления запроса клиента на определенный метод обработчика. Обратите внимание, что методы обработчика возвращают строку, которая будет использоваться в качестве ответа. Как видите, у нас есть три метода, возвращающих разные строки, поэтому нам нужно создать JSP-страницы с теми же именами. Обратите внимание, что метод login() будет вызываться с использованием метода POST, поэтому мы ожидаем некоторые данные формы. У нас есть класс модели User, который помечен для валидации с использованием аннотации @Validated. Каждый метод содержит аргумент Model, и мы можем установить атрибуты, которые будут использоваться в JSP-страницах ответа.
Классы модели Spring MVC
Классы модели используются для хранения переменных формы, наша модель User выглядит следующим образом.
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 – Страницы представления
У нас есть три 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>
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>
Простая домашняя страница для пользователя, на которой отображается имя пользователя. Обратите внимание, что мы устанавливаем этот атрибут в методе входа.
Пример приложения Spring MVC Testing
Наше приложение готово к выполнению, просто запустите его на сервере VMware tc или на вашем выборе любого другого контейнера сервлетов, вы получите следующие страницы в качестве ответа.
Вот и всё для учебника по Spring MVC, вы можете увидеть, насколько легко создать приложение Spring MVC, используя плагины STS. Размер кода очень маленький, и большая часть конфигурации обрабатывается Spring MVC, чтобы мы могли сосредоточиться на бизнес-логике. Скачайте пример проекта Spring MVC по ссылке ниже и поиграйтесь с ним.
Source:
https://www.digitalocean.com/community/tutorials/spring-mvc-tutorial