このガイドでは、検証をサポートするために Web アプリケーションフォームを構成するプロセスを順を追って説明します。

構築するもの

ユーザー入力を取得し、標準の検証アノテーションを使用して入力をチェックする簡単な Spring MVC アプリケーションを構築します。また、ユーザーが入力を再入力して有効にするために、画面にエラーメッセージを表示する方法もわかります。

必要なもの

このガイドを完了する方法

ほとんどの Spring 入門ガイドと同様に、最初から始めて各ステップを完了するか、すでに慣れている場合は基本的なセットアップステップをバイパスできます。いずれにしても、最終的に動作するコードになります。

最初から始めるには、Spring Initializr から開始に進みます。

基本スキップするには、次の手順を実行します。

完了したときは、gs-validating-form-input/complete のコードに対して結果を確認できます。

Spring Initializr から開始

すべての Spring アプリケーションの場合、Spring Initializr (英語) から開始する必要があります。Initializr は、アプリケーションに必要なすべての依存関係をすばやく取り込む方法を提供し、多くのセットアップを行います。この例では、Spring、Web、および Thymeleaf の依存関係が必要です。次のイメージは、このサンプルプロジェクト用に設定された Initializr を示しています。

initializr
前の図は、Maven がビルドツールとして選択された Initializr を示しています。Gradle も使用できます。また、com.example および validating-form-input の値をそれぞれグループおよびアーティファクトとして表示します。このサンプルの残りの部分では、これらの値を使用します。

次のリストは、Maven を選択したときに作成される pom.xml ファイルを示しています。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>validating-form-input</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>validating-form-input</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

次のリストは、Gradle を選択したときに作成される build.gradle ファイルを示しています。

plugins {
	id 'org.springframework.boot' version '2.2.2.RELEASE'
	id 'io.spring.dependency-management' version '1.0.8.RELEASE'
	id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation('org.springframework.boot:spring-boot-starter-test') {
		exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
	}
}

test {
	useJUnitPlatform()
}

PersonForm オブジェクトを作成する

このアプリケーションでは、ユーザーの名前と年齢を検証する必要があるため、最初に、個人の作成に使用されるフォームを支援するクラスを作成する必要があります。次のリスト(src/main/java/com/example/validatingforminput/PersonForm.java から)は、その方法を示しています。

package com.example.validatingforminput;

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

public class PersonForm {

	@NotNull
	@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 + ")";
	}
}

PersonForm クラスには、name と age の 2 つの属性があります。いくつかの標準検証アノテーションが付いています:

  • @Size(min=2, max=30): 2 〜 30 文字の名前を使用できます。

  • @NotNull: null 値は許可されません。これは、エントリが空の場合に Spring MVC が生成するものです。

  • @Min(18): 年齢を 18 歳未満にすることはできません。

それに加えて、name と age の getter と setter および便利な toString() メソッドも見ることができます。

Web コントローラーを作成する

フォームバッキングオブジェクトを定義したため、今度は単純な Web コントローラーを作成します。次のリスト(src/main/java/com/example/validatingforminput/WebController.java から)は、その方法を示しています。

package com.example.validatingforminput;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


@Controller
public class WebController implements WebMvcConfigurer {

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

	@GetMapping("/")
	public String showForm(PersonForm personForm) {
		return "form";
	}

	@PostMapping("/")
	public String checkPersonInfo(@Valid PersonForm personForm, BindingResult bindingResult) {

		if (bindingResult.hasErrors()) {
			return "form";
		}

		return "redirect:/results";
	}
}

このコントローラーには、GET メソッドと POST メソッドがあります。両方のメソッドは / にマップされます。

showForm メソッドは、form テンプレートを返します。テンプレートがフォーム属性を PersonForm に関連付けることができるように、メソッド署名に PersonForm が含まれています。

checkPersonFormInfo メソッドは、2 つの引数を受け入れます。

  • フォームに記入された属性を収集するために @Valid でマークされた personForm オブジェクト。

  • bindingResult オブジェクト。検証エラーをテストおよび取得できます。

PersonForm オブジェクトにバインドされているフォームからすべての属性を取得できます。コードでは、エラーをテストします。エラーが発生した場合、ユーザーを元の form テンプレートに戻すことができます。その場合、すべてのエラー属性が表示されます。

すべての人物の属性が有効な場合、ブラウザは最終的な results テンプレートにリダイレクトされます。

HTML フロントエンドを構築する

次のリスト(src/main/resources/templates/form.html から)が示すように、「メイン」ページを作成します。

<html>
    <body>
        <form action="#" th:action="@{/}" th:object="${personForm}" 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}">Age Error</td>
                </tr>
                <tr>
                    <td><button type="submit">Submit</button></td>
                </tr>
            </table>
        </form>
    </body>
</html>

このページには単純なフォームが含まれており、各フィールドはテーブル内の個別のセルにあります。フォームは / に投稿するように調整されています。Web コントローラーの GET メソッドで確認した personForm オブジェクトによってバックアップされているとマークされています。これは「bean-backed form」として知られています。PersonForm Bean には 2 つのフィールドがあり、th:field="{name}" および th:field="{age}" でタグ付けされていることがわかります。各フィールドの横には、検証エラーを表示するために使用されるセカンダリ要素があります。

最後に、フォームを送信するボタンがあります。一般的に、ユーザーが @Valid 制約に違反する名前または年齢を入力すると、エラーメッセージが表示されてこのページに戻ります。有効な名前と年齢が入力されると、ユーザーは次の Web ページにルーティングされます。

次の例(src/main/resources/templates/results.html から)は、結果ページを示しています。

<html>
	<body>
		Congratulations! You are old enough to sign up for this site.
	</body>
</html>
この単純な例では、これらの Web ページには洗練された CSS や JavaScript はありません。

アプリケーションの実行

このアプリケーションでは、Thymeleaf (英語) のテンプレート言語を使用しています。このアプリケーションには、生の HTML 以上のものが必要です。Spring Initializr がアプリケーションクラスを作成しました。次のリスト(src/main/java/com/example/validatingforminput/ValidatingFormInputApplication.java から)は、そのクラスを示しています。

package com.example.validatingforminput;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ValidatingFormInputApplication {

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

}

Spring MVC をアクティブにするには、通常、@EnableWebMvc を Application クラスに追加します。ただし、Spring Boot の @SpringBootApplication は、クラスパスで spring-webmvc を検出すると、このアノテーションを既に追加しています。この同じアノテーションにより、アノテーション付きの @Controller クラスとそのメソッドを見つけることができます。

Thymeleaf 構成も @SpringBootApplication によって処理されます。デフォルトでは、テンプレートは templates/ のクラスパスにあり、ファイル名から「.html」接尾辞を取り除くことによりビューとして解決されます。(Thymeleaf 設定は、達成する必要があるものに応じて、さまざまな方法で変更およびオーバーライドできますが、詳細はこのガイドには関係ありません。)

実行可能 JAR を構築する

コマンドラインから Gradle または Maven を使用してアプリケーションを実行できます。必要なすべての依存関係、クラス、およびリソースを含む単一の実行可能 JAR ファイルを構築して実行することもできます。実行可能な jar を構築すると、開発ライフサイクル全体、さまざまな環境などで、サービスをアプリケーションとして簡単に提供、バージョン管理、およびデプロイできます。

Gradle を使用する場合、./gradlew bootRun を使用してアプリケーションを実行できます。または、次のように、./gradlew build を使用して JAR ファイルをビルドしてから、JAR ファイルを実行できます。

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

Maven を使用する場合、./mvnw spring-boot:run を使用してアプリケーションを実行できます。または、次のように、./mvnw clean package で JAR ファイルをビルドしてから、JAR ファイルを実行できます。

java -jar target/gs-validating-form-input-0.1.0.jar
ここで説明する手順は、実行可能な JAR を作成します。クラシック WAR ファイルを作成することもできます。

アプリケーションは数秒以内に稼働します。

http://localhost:8080/ にアクセスすると、次のイメージのようなものが表示されるはずです。

valid 01

次のイメージのペアは、名前に A を入力し、年齢に 15 を入力してサブミットをクリックするとどうなるかを示しています。

valid 02
valid 03

上記のイメージは、値が PersonForm クラスの制約に違反しているため、「メイン」ページに戻ることを示しています。入力ボックスに何もない状態でサブミットをクリックすると、次のイメージに示すように、別のエラーが表示されることに注意してください。

valid 04

有効な名前と年齢を入力すると、次の図に示すように、results ページが表示されます。

valid 05

要約

おめでとう!ドメインオブジェクトに検証が組み込まれた単純な Web アプリケーションをコーディングしました。これにより、データが特定の条件を満たしていること、およびユーザーがデータを正しく入力したことを確認できます。

関連事項

次のガイドも役立ちます。

新しいガイドを作成したり、既存のガイドに貢献したいですか? 投稿ガイドラインを参照してください (GitHub)

すべてのガイドは、コード用の ASLv2 ライセンス、およびドキュメント用の Attribution、NoDerivatives クリエイティブコモンズライセンス (英語) でリリースされています。