Учебные материалы

Проверка введенных данных

Этот урок освещает процесс создания web-приложения с поддержкой валидации.

Что вы создадите

Вы создадите простое Spring MVC приложение, которое принимает введенные пользователем данные и проверяет их, используя стандартные аннотации для валидации. Вы также увидите, как отобразить сообщения об ошибке, чтобы пользователь повторно ввел правильные данные.

Что вам потребуется

  • Примерно 15 минут свободного времени
  • Любимый текстовый редактор или IDE
  • JDK 6 и выше
  • Gradle 1.11+ или Maven 3.0+
  • Вы также можете импортировать код этого урока, а также просматривать web-страницы прямо из Spring Tool Suite (STS), собственно как и работать дальше из него.

Как проходить этот урок

Как и большинство уроков по Spring, вы можете начать с нуля и выполнять каждый шаг, либо пропустить базовые шаги, которые вам уже знакомы. В любом случае, вы в конечном итоге получите рабочий код.

Чтобы начать с нуля, перейдите в Настройка проекта.

Чтобы пропустить базовые шаги, выполните следующее:

Когда вы закончите, можете сравнить получившийся результат с образцом в gs-validating-form-input/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-validating-form-input'
    version =  '0.1.0'
}

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "http://repo.spring.io/libs-release" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    compile("org.hibernate:hibernate-validator")
    compile("org.apache.tomcat.embed:tomcat-embed-el")
    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 выбранным набором версий

Создание объекта Person

Приложение включает проверку пользовательских имени и возраста, т. о. ва необходимо создать класс, представляющего человека.

src/main/java/hello/Person.java

package hello;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class Person {

    @Size(min=2, max=30)
    private String name;

    @NotNull
    @Min(18)
    private Integer age;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String toString() {
        return "Person(Name: " + this.name + ", Age: " + this.age + ")";
    }

}

Класс Person имеет два атрибута: name и age. Они помечены несколькими стандартными аннотациями валидации.

  • @Size(min=2, max=30) - длина имени от 2 до 30 символов
  • @NotNull - недопустимость null значения, которое Spring MVC генерирует, если запись пуста
  • @Min(18) - значение должно быть не меньше 18

Создание web контроллера

Теперь, когда вы описали сущность, пришло время создать простой web-контроллер.

src/main/java/hello/WebController.java

package hello;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Controller
public class WebController extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/results").setViewName("results");
    }

    @RequestMapping(value="/", method=RequestMethod.GET)
    public String showForm(Person person) {
        return "form";
    }

    @RequestMapping(value="/", method=RequestMethod.POST)
    public String checkPersonInfo(@Valid Person person, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "form";
        }
        return "redirect:/results";
    }

}

Этот контроллер имеет GET и POST методы, оба относятся к /.

Метод showForm возвращает шаблон form. Он включает Person в своей сигнатуре, что позволяет соответствующие атрибуты с Person.

Метод checkPersonInfo принимает два аргумента:

  • person объект помечен как @Valid для получения заполненных атрибутов из формы
  • bindingResult объектом вы можете проверить на ошибки и вернуть их

Вы можете вернуть все атрибуты из формы, связанной с объектом Person. В коде вы проверяете на существование ошибок и, если они есть, то отправляете обратно шаблон form. В данной ситуации все ошибки атрибутов отображены.

Если все атрибуты верны, то браузер перенаправляет на шаблон results.

Создание HTML формы

Теперь вы создадите "главную" страницу.

src/main/resources/templates/form.html

<html>
    <body>
        <form action="#" th:action="@{/}" th:object="${person}" method="post">
            <table>
                <tr>
                    <td>Name:</td>
                    <td><input type="text" th:field="*{name}" /></td>
                    <td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</td>
                </tr>
                <tr>
                    <td>Age:</td>
                    <td><input type="text" th:field="*{age}" /></td>
                    <td th:if="${#fields.hasErrors('age')}" th:errors="*{age}">Name Error</td>
                </tr>
                <tr>
                    <td><button type="submit">Submit</button></td>
                </tr>
            </table>
        </form>
    </body>
</html>

Страница содержит простую форму, где каждое поле расположена на отдельной строке таблицы. Форма предназначена на отправку к /. Она представляет person объект, который вы видели в GETметоде в web-контроллере. Форма представляет собой известную bean-backed форму. В ней два поля Person бина, th:field="*{name}" и th:field="*{age}". Следующие за ними поля использованы для отображения любых ошибок валидации.

В итоге, вы нажимаете кнопку "Submit". Если введенные пользователем имя и возраст противоречат ограничениям @Valid, то ему вернется та же страница, но с отображенными ошибками. Если введенные имя и возраст правильны, то пользователь будет перенаправлен на следующую web-страницу:

src/main/resources/templates/results.html

<html>
	<body>
		Congratulations! You are old enough to sign up for this site.
	</body>
</html>

Создание Application класса

В этом приложении вы используете язык шаблонов Thymeleaf. Этому приложению необходимо больше, чем просто HTML.

src/main/java/hello/Application.java

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }

}

Для активации Spring MVC вы обычно добавляете @EnableWebMvc к Application классу. Но Spring Boot @EnableAutoConfiguration уже добавляет эту аннотацию, когда обнаруживает spring-webmvc в вашем classpath. Это приложение также содержит @ComponentScan, которая находит аннотированные @Controller классы и их методы.

Thymeleaf конфигурация также обнаруживается через @EnableAutoConfiguration: по умолчанию шаблоны расположены в templates/ и определяются как представления без учета суффикса .html в имени файла. Настройки Thymeleaf могут быть изменены и переопределены различными способами в зависимости от вашей задачи, но мы не будет рассматривать это в данном уроке.

Сборка исполняемого JAR

Вы можете собрать единый исполняемый JAR-файл, который содержит все необходимые зависимости, классы и ресурсы. Это делает его легким в загрузке, версионировании и развертывании сервиса как приложения на протяжении всего периода разработки, на различных средах и так далее.

./gradlew build

Затем вы можете запустить JAR-файл:

java -jar build/libs/gs-validating-form-input-0.1.0.jar

Если вы используете Maven, вы можете запустить приложение, используя mvn spring-boot:run, либо вы можете собрать приложение с mvn clean package и запустить JAR примерно так:

java -jar target/gs-validating-form-input-0.1.0.jar
Процедура, описанная выше, создает исполняемый JAR. Вы также можете вместо него собрать классический WAR-файл.

Запуск сервиса

Если вы используете Gradle, вы можете запустить ваш сервис из командной строки:

./gradlew clean build && java -jar build/libs/gs-validating-form-input-0.1.0.jar
Если вы используете Maven, то можете запустить ваш сервис таким образом: mvn clean package && java -jar target/gs-validating-form-input-0.1.0.jar.

Как вариант, вы можете запустить ваш сервис напрямую из Gradle примерно так:

./gradlew bootRun
С mvn - mvn spring-boot:run.

Приложение должно быть поднято и запущено через несколько секунд.

Если вы зайдете на http://localhost:8080/, то должны увидеть следующее:

Что будет, если вы введете A для имени и 15 для возраста и нажмете Submit?

Вы увидете это потому, что введенные значения нарушают ограничения в классе Person. Если вы нажмете Submit c пустым значением поля ввода возраста, то получите другую ошибку.

Ели вы введете правильные имя и возраст, то отобразится results страница!

Итог

Поздравляем! Вы только что разработали простое web-приложение со встроенной проверкой в объекте. Этим способом вы можете наделить данные соответствующими критериями для корректного ввода пользователем.

С оригинальным текстом урока вы можете ознакомиться на spring.io.

comments powered by Disqus