Обработка данных формы
Этот урок освещает процесс использования Spring для создания и отправки web формы.
Что вы создадите
В этом уроке вы создадите web форму, которая будет доступна по URL:
http://localhost:8080/greeting
При просмотре этой страницы отобразится форма. Вы сможете отправить сообщение, заполнив
поля id
и content
. Результирующая страница будет отображена,
когда форма будет отправлена.
Что вам потребуется
- Примерно 15 минут свободного времени
- Любимый текстовый редактор или IDE
- JDK 6 и выше
- Gradle 1.11+ или Maven 3.0+
- Вы также можете импортировать код этого урока, а также просматривать web-страницы прямо из Spring Tool Suite (STS), собственно как и работать дальше из него.
Как проходить этот урок
Как и большинство уроков по Spring, вы можете начать с нуля и выполнять каждый шаг, либо пропустить базовые шаги, которые вам уже знакомы. В любом случае, вы в конечном итоге получите рабочий код.
Чтобы начать с нуля, перейдите в Настройка проекта.
Чтобы пропустить базовые шаги, выполните следующее:
- Загрузите и
распакуйте архив с кодом этого урока, либо кнонируйте из репозитория с помощью
Git:
git clone https://github.com/spring-guides/gs-handling-form-submission.git
- Перейдите в каталог
gs-handling-form-submission/initial
- Забегая вперед, создайте web контроллер
Когда вы закончите, можете сравнить получившийся результат с образцом в gs-handling-form-submission/complete
.
Настройка проекта
Для начала вам необходимо настроить базовый скрипт сборки. Вы можете использовать любую систему сборки, которая вам нравится для сборки проетов Spring, но в этом уроке рассмотрим код для работы с Gradle и Maven. Если вы не знакомы ни с одним из них, ознакомьтесь с соответсвующими уроками Сборка Java-проекта с использованием Gradle или Сборка Java-проекта с использованием Maven.
Создание структуры каталогов
В выбранном вами каталоге проекта создайте следующую структуру каталогов; к примеру,
командой mkdir -p src/main/java/hello
для *nix систем:
└── src └── main └── java └── hello
Создание файла сборки Gradle
Ниже представлен начальный файл сборки Gradle. Файл pom.xml находится здесь. Если вы используете Spring Tool Suite (STS), то можете импортировать урок прямо из него.
pom.xml
, вы найдете, что указана версия для maven-compiler-plugin.
В общем, это не рекомендуется делать. В данном случае он предназначен для решения проблем с нашей CI системы,
которая по умолчанию имеет старую(до Java 5) версию этого плагина.
build.gradle
buildscript {
repositories {
maven { url "http://repo.spring.io/libs-release" }
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.8.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
jar {
baseName = 'gs-handling-form-submission'
version = '0.1.0'
}
repositories {
mavenLocal()
mavenCentral()
maven { url "http://repo.spring.io/libs-release" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
testCompile("junit:junit")
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
Spring Boot gradle plugin предоставляет множество удобных возможностей:
- Он собирает все jar'ы в classpath и собирает единое, исполняемое "über-jar", что делает более удобным выполнение и доставку вашего сервиса
- Он ищет
public static void main()
метод, как признак исполняемого класса - Он предоставляет встроенное разрешение зависимостей, с определенными номерами версий для соответсвующих Spring Boot зависимостей. Вы можете переопределить на любые версии, какие захотите, но он будет по умолчанию для Boot выбранным набором версий
Создание web контроллера
В подходе Spring к построению web сайтов, HTTP запросы обрабатываются контроллером.
Эти компоненты легко идентифицируются по @Controller
аннотации.
Ниже представленный GreetingController
обрабатывает GET запросы для
/greeting
, возвращая название
View
,
в данном случае это "greeting". View
ответственнен за рендеринг HTML
контента.
src/main/java/hello/GreetingController.java
package hello;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class GreetingController {
@RequestMapping(value="/greeting", method=RequestMethod.GET)
public String greetingForm(Model model) {
model.addAttribute("greeting", new Greeting());
return "greeting";
}
@RequestMapping(value="/greeting", method=RequestMethod.POST)
public String greetingSubmit(@ModelAttribute Greeting greeting, Model model) {
model.addAttribute("greeting", greeting);
return "result";
}
}
Этот контроллер лаконичен и прост, но в нем много чего происходит. Давайте подробнее рассмотрим шаг за шагом.
Аннотация @RequestMapping
позволяет вам связать HTTP запросы с
определенными методами контроллера. В этом контроллере два метода и оба они
относятся к /greeting
. По умолчанию, @RequestMapping
соответствует всем HTTP операциям, таким как GET
, POST
и так далее. Но в данном случае метод greetingForm()
явно связан с
GET
, используя @RequestMapping(method=GET)
, в то время
как greetingSubmit()
связан с POST
через
@RequestMapping(method=POST)
. Эти соответствия позволяют контроллеру
различать типы запросов к /greeting
.
Метод greetingForm()
использует объект
Model
для предоставления доступа к новому Greeting
в шаблоне представления.
Greeting
объект в приведенном ниже коде содержит поля id
и content
, соответствующие полям формы в greeting
представлении,
и которые будут использованы для извлечения информации из формы.
src/main/java/hello/Greeting.java
package hello;
public class Greeting {
private long id;
private String content;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
Реализация тела метода основана на
View Technology,
в данном случае на Thymeleaf,
чтобы выполнять рендеринг HTML на стороне сервера. Thymeleaf парсит шаблон greeting.html
,
приведенный ниже, и вычисляет различные выражения для рендеринга формы.
src/main/resources/templates/greeting.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Handing Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Form</h1>
<form action="#" th:action="@{/greeting}" th:object="${greeting}" method="post">
<p>Id: <input type="text" th:field="*{id}" /></p>
<p>Message: <input type="text" th:field="*{content}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</body>
</html>
Выражение th:action="@{/greeting}"
направляет форму к POST запросу
/greeting
, в то время как выражение th:object="${greeting}"
описывает модель объекта для сбора данных. Два поля формы, выраженные в
th:field="*{id}"
и th:field="*{content}"
, соответствуют
полям объекта Greeting
.
Это то, за что отвечает контроллер, модель и представление для отображения формы.
Теперь давайте рассмотрим процесс отправки формы. Как уже отмечалось выше, форма
отправляется на /greeting
, используя POST
. Метод
greetingSubmit()
получает объект Greeting
, который
был заполнен формой. Затем он добавляет этот объект в модель для того, чтобы
отправленные данные могли быть отображены в представлении result
,
как показано ниже. id
представлен в выражении
<p th:text="'id: ' + ${greeting.id}" />
. Аналогично,
content
представлен в выражении
<p th:text="'content: ' + ${greeting.content}" />
src/main/resources/templates/result.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Handing Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Result</h1>
<p th:text="'id: ' + ${greeting.id}" />
<p th:text="'content: ' + ${greeting.content}" />
<a href="/greeting">Submit another message</a>
</body>
</html>
Для наглядности, этот пример использует два отдельных шаблона представления для рендеринга формы и отображения отправленных данных; однако никто вам не мешает использовать одно представление для обеих целей.
Создание приложения исполняемым
Несмотря на то, что пакет этого сервиса может быть в составе web-приложения и
WAR файлов,
более простой подход, продемонстрированный ниже создает отдельное самостоятельное приложение.
Вы упаковываете все в единый, исполняемый JAR-файл, который запускается через хорошо знакомый
старый main()
Java-метод. Попутно, вы используете поддержку Spring для встроенного
Tomcat
контейнера сервлетов как HTTP среду выполнения вместо развертывания на сторонний экземпляр.
src/main/java/hello/Application.java
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Метод main()
передает управление вспомогательному классу
SpringApplication
, предоставляя Application.class
как аргумент его run()
методу. Это говорит Spring о том, чтобы
прочитать аннотацию метаданных из Application
и управлять им
как компонентом в Spring Application Context.
Аннотация @ComponentScan
сообщает Spring о запуске рекурсивного
поиска в пакете hello
и потомках классов, отмеченных прямо или
косвенно Spring аннотацией @Component
. При этом гарантируется,
что Spring найдет и зарегистрирует GreetingController
,
потому что он отмечен @Controller
, что в свою очередь является
своего рода @Component
аннотацией.
@EnableAutoConfiguration
аннотация переключает на доступные по умолчанию настройки, основанные на
содержимом вашего classpath. К примеру, т.к. приложение зависит от встраиваемой
версии Tomcat(tomcat-embed-core.jar), то Tomcat сервер установлен и настроен
по умолчанию от вашего имени. И также, т.к. приложение зависит от Spring MVC
(spring-webmvc.jar), Spring MVC DispatcherServlet
настроен и зарегистрирован за вас - web.xml
не нужен!
Автонастройка является мощным и гибким механизмом. Более подробно вы можете
ознакомиться в API документации.
Сборка исполняемого JAR
Вы можете собрать единый исполняемый JAR-файл, который содержит все необходимые зависимости, классы и ресурсы. Это делает его легким в загрузке, версионировании и развертывании сервиса как приложения на протяжении всего периода разработки, на различных средах и так далее.
./gradlew build
Затем вы можете запустить JAR-файл:
java -jar build/libs/gs-handling-form-submission-0.1.0.jar
Если вы используете Maven, вы можете запустить приложение, используя mvn spring-boot:run
,
либо вы можете собрать приложение с mvn clean package
и запустить JAR примерно так:
java -jar target/gs-handling-form-submission-0.1.0.jar
Если вы используете Gradle, вы можете запустить ваш сервис из командной строки:
./gradlew clean build && java -jar build/libs/gs-handling-form-submission-0.1.0.jar
mvn clean package && java -jar target/gs-handling-form-submission-0.1.0.jar
.
Как вариант, вы можете запустить ваш сервис напрямую из Gradle примерно так:
./gradlew bootRun
mvn spring-boot:run
.Выходные данные отображены. Сервис должен быть поднят и запущен через несколько секунд.
Тестирование сервиса
Теперь, когда web сайт запущен, перейдите по адресу http://localhost:8080/greeting, где вы увидите форму:
Отправьте id и message, чтобы посмотреть на результат:
Итог
Поздравляем! Вы только что использовали Spring для создания и отправки формы.
С оригинальным текстом урока вы можете ознакомиться на spring.io.
comments powered by Disqus