0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

エラーメッセージを表示する、エラーメッセージをカスタマイズする。

Posted at

SpringBoot:エラーメッセージを表示

以下のことを実施します。
  1.エラーメッセージを表示する。
  2.メッセージの国際化対応
  3.Webjarsを使用

依存関係は以下の通り

  ・Spring Boot Dev Tools
  ・Lombok
  ・検証
  ・Thymeleaf
  ・Spring Web

モデルの作成

 @NotBlank@Sizeはバリデーション用のアノテーション。
 これらを使用することでエラーチェックを簡単に実装できる

package com.example.demo;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter


public class Inquiry {

	@NotBlank
	@Size(max=60)

	private String name;
	@NotBlank
	@Email
	@Size(max = 254)
	private String email;

	@NotBlank
	@Size(max=500)
	private String inquiry;
}

コントローラを作成

 
 @Validated
  入力値のチェックを行う
  チェックの結果は、BindingResultに入るので
  result.hasErrors()でエラーがあるか確認できる

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

@Controller

public class HomeController {

	@GetMapping("/")
	public String index(@ModelAttribute Inquiry inquiry) {
		return"index";
	}
	@PostMapping("/")
	public String confirm(@Validated@ModelAttribute Inquiry inquiry, BindingResult result) {
		if(result.hasErrors()) {
			return"index";
		}
		return"confirm";
	}

}

Bootstrapを追加

・Bootstrapとは
  BootstrapはCSSやjavaScriptから構成されるフレームワーク
  きれいな画面がつくれることやPCやスマートフォンなどに自動対応する画面
  が作れる。
 
・pom.xmlを編集
 dependenciesタグ内に以下の2つを追加

		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>bootstrap</artifactId>
			<version>4.5.0</version>
		</dependency>
		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>webjars-locator</artifactId>
			<version>0.40</version>
		</dependency>

Thymeleafを作成

 index.htmlを作成し以下のソースを記載

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet"th:href="@{/webjars/bootstrap/css/bootstrap.min.css}">
<title>Title</title>
</head>
	<body class="bg-light">
		<div class="contatiner">
			<div class="row justify-content-md-center">
				<div class="col-md-8">
					<h4 class="border-bottom my-3" th:text="#{inquiry}"></h4>
					<form th:action="@{/}" th:object="${inquiry}"method="post" novalidate>
						<div class="form-group">
							<label for = "name" th:text="#{name}"></label>
							<input type="text" class ="form-control" th:errorclass="is-invalid" th:field="*{name}">
							<div class="invalid-feedback" th:errors="*{name}"></div>
						</div>
						<div class="form-group">
							<label for="email" th:text="#{email}"></label>
							<input type="email" class="form-control" th:errorclass="is-invalid" th:field="*{email}">
							<div class="invalid-feedback" th:errors="*{email}"></div>
						</div>
						<div class="form-group">
							<label for="inquiry" th:text="#{inquiry}"></label>
							<textarea class="form-control" rows="3" th:errorclass="is-invalid" th:field="*{inquiry}"></textarea>
							<div class="invalid-feedback" th:errors="*{inquiry}"></div>
						</div>
						<button class="btn btn-primary btn-lg btn-block my-4" type="submit" th:text="#{register}"></button>
					</form>
				</div>
			</div>
		</div>
		<script th:src="@{/webjars/jquery/jquery.min.js}"></script>
		<script th:src="@{/webjars/popper.js/umd/popper.min.js}"></script>
		<script th:sec="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
	</body>
</html>

登録完了画面を作成

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" th:href="@{/webjar/bootstrap/css/bootstrap.min.css}">
<title>title</title>
</head>
<body class="bg-light">
	<div class="container">
		<div class="row justify-content-md-center">
			<div class="col-md-8">
				<h4 class="border-bottom my-3" th:text="#{inquiry}"></h4>
				<p class="text-danger" th:text="#{confirmationMessage}"></p>
				<div th:object="${inquiry}">
					<div class="form-group">
						<label for="password" th:text="#{name}"></label>
						<input type="text" class="form-control"th:field="*{name}" disabled>
					</div>
					<div class="form-group">
						<label for="email" th:text="#{email}"></label>
						<input type="email" class="form-control" th:field="*{email}"disabled>
					</div>
					<div class="form-group">
						<label for="inquiry" th:text="#{inquiry}"></label>
						<textarea class="form-control" rows="3" th:field="*{inquiry}"disabled></textarea>
					</div>
				</div>
			</div>
		</div>
	</div>
	<script th:src="@{/webjars/jquery/jquery.min.js}"></script>
	<script th:src="@{/webjars/popper.js/umd/popper.min.js}"></script>
	<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
</body>
</html>

メッセージの国際化対応

 messages_ja.prpertiesとmessages.propertiesを作成し以下のように編集する
 
 ・messages.ja.properties
  inquiry=お問い合わせ
  name=お名前
  email=Email
  register=登録
  confirmationMessage=以下の内容で登録が完了しました。
 ・messages.properties
  inquiry=Inquiry
  name=Name
  email=Email
  register=Register
  confimationMessage=Registration has been completed with the following

確認

ブラウザでhttp://localhost:8080/を開き文字を入力後登録ボタンを押下
課題14.png

その後登録画面が表示されるか確認
課題15.png

また、空欄の状態で登録ボタンを押下しエラーメッセージが表示されるか確認
課題13.png

エラーメッセージをカスタマイズする

 以下のことを実施します。
 ・エラーメッセージをカスタマイズする
 ・国際化メッセージを設定する

依存関係

 ・Spring Boot Dev Tools
 ・Lombok
 ・検証
 ・Thymeleaf
 ・Spring Web

モデルの作成

 
 @NumberFomat(@pattern="#,###")
  指定パターンの文字列を数値に型変換します。

 @DateTimeFormat(iso = ISO.DATE)
  ISOパターンの文字列を日付に型変換します。

package com.example.demo.model;

import java.math.BigDecimal;
import java.time.LocalDate;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.format.annotation.NumberFormat;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Invoice {

	@NotBlank
	@Size(max=60)
	private String address;
	
	@NotBlank
	@Pattern(regexp ="[0-9-]*")
	private String phoneNumber;
	
	@NotNull
	@Min(1000)
	@NumberFormat(pattern="#,###")
	private BigDecimal price;
	
	@NotNull
	@DateTimeFormat(iso=ISO.DATE)
	private LocalDate paymentDeadline;

}

コントローラ作成

 

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

import com.example.demo.model.Invoice;

@Controller
public class HomeController {

	@GetMapping("/")
	public String index(@ModelAttribute Invoice invoice) {
		return"index";
	}
	
	@PostMapping("/")
	public String confirm(@Validated @ModelAttribute Invoice invoice,BindingResult result) {
		if(result.hasErrors()) {
			return"index";
		}
		return"confirm";
	}
	
	
}

Bootstrapを追加

 pom.xmlを開き以下を追加

<dependency>
		<groupId>org.webjars</groupId>
		<artifactId>bootstrap</artifactId>
		<version>4.5.0</version>
		</dependency>
		<dependency>
		<groupId>org.webjars</groupId>
		<artifactId>webjars-locator</artifactId>
		<version>0.40</version>
</dependency>

Thymeleafを作成

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" th:href="@{/webjars/bootstrap/css/bootstrap.min.css}">
<title>title</title>
</head>
<body class="bg-light">
 <div class="contatiner">
 	<div class="row justify-content-md-center">
 		<div class="col-md-8">
 			<h4 class="border-bottom my-3" th:text="#{invoice}"></h4>
 			<form th:action="@{/}" th:object="${invoice}" method="post" novalidate>
 				<div class="form-group">
 					<label for="name" th:text="#{name}"></label>
 					<input type="text" class="form-control" th:errorclass="is-invalid" th:field="*{name}">
 					<div class="invalid-feedback" th:errors="*{name}"></div>
 					</div>
 				<div class="form-group">
 					<label for="address" th:text="#{address}"></label>
 					<input type="text" class="form-control"th:errorclass="is-invalid"th:field="*{address}">
 					<div class="invalid-feedback"th:errors="*{address}"></div>
 				</div>
 				<div class="form-group">
 					<label for="phone"th:text="#{phoneNumber}"></label>
 					<input type="tel"class="form-control"th:errorclass="is-invalid"th:field="*{phoneNumber}">
 					<div class="invalid-feedback"th:errors="*{phoneNumber}"></div>
 				</div>
 				<div class="form-group">
 					<label for="price" th:text="#{price}"></label>
 					<input type="text" class="form-control" th:errorclass="is-invalid"th:field="*{price}">
 					<div class="invalid-feedback"th:errors="*{price}"></div>
 				</div>
 				<div class="form-group">
 					<label for="paymentDeadline" th:text="#{paymentDeadline}"></label>
 					<input type="date"class="form-control" th:errorclass="is-invalid" th:field="*{paymentDeadline}">
 					<div class="invalid-feedback"th:errors="*{paymentDeadline}"></div>
 				</div>
 				<button class="btn btn-primary btn-lg btn-block my-4" type="submit" th:text="#{register}"></button>
 			</form>
 		</div>"
 	</div>
 </div>
<script th:src="@{/webjars/jquery/jquery.min.js}"></script>
<script th:src="@{/webjars/popper.js/umd/popper.min.js}"></script>
<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
</body>
</html>

登録完了画面作成

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet"th:href="@{/webjars/bootstrap/css/bootstrap.min.css}">
<title>title</title>
</head>
<body class="bg-light">
	<div class="container">
		<div class="row justify-content-md-center">
			<div class="col-md-8 order-md-1">
				<h4 class="border-bottom my-3"th:text="#{invoice}"></h4>
				<p class="text-danger"th:text="#{confirmationMessage}"></p>
				<div th:object="${invoice}">
					<div class="form-group">
						<label for="name"th:text="#{name}"></label>
						<input type="text"class="form-control"th:field="*{name}" disabled>
					</div>
					<div class="form-group">
						<label for="address"th:text="#{address}"></label>
						<input type="text" class="form-control"th:field="*{address}"disabled>	
					</div>
					<div class="form-group">
						<label for="phoneNumber"th:text="#{phoneNumber}"></label>
						<input type="tel" class="form-control"th:field="*{phoneNumber}"disabled>
					</div>
					<div class="form-group">
						<label for="price"th:text="#{price}"></label>
						<input type="text" class="form-control"th:field="*{price}" disabled>
					</div>
					<div class="form-group">
						<label for="paymentDeadline"th:text="#{paymentDeadline}"></label>
						<input type="date" class="form-control"th:field="*{paymentDeadline}"disabled>
					</div>
				</div>
			</div>
		</div>
	</div>
	<script th:src="@{/webjars/jquery/jquery.min.js}"></script>
	<script th:src="@{/webjars/popper.js/umd/popper.min.js}"></script>
	<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
</body>
</html>

メッセージコンフィグ作成

 @configuration
  設定クラスであることを示す
 @bean
  Springに管理されるBeanの生成を示す。

package com.example.demo.config;

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

@Configuration
public class MessageConfig {

	@Bean
	public MessageSource messageSource() {
		var source= new ReloadableResourceBundleMessageSource();
		source.setBasenames("classpath:i18n/messages","classpath:i18n/ValidationMessages");
		source.setDefaultEncoding("UTF-8");
		source.setFallbackToSystemLocale(false);
		return source;
	}
	@Bean
	public LocalValidatorFactoryBean getValidator() {
		var bean = new LocalValidatorFactoryBean();
		bean.setValidationMessageSource(messageSource());
		return bean;
	}
}

メッセージを追加

以下のファイルを作成後編集
 ・messages_jp.properties

invoice=請求書
name=お客様名
address =住所
phoneNumber=電話番号
price = 金額
paymentDeadline =支払期日
register =登録
confirmationMessage =登録が正常に完了しました。

 ・messages.properties

invoice = Invoice
name = Name
address = Address
phoneNumber = Phone number
price = Price
paymentDeadline = Payment deadline register = Register
confirmationMessage = Registration has been successfully completed

 ・ValidationMessages_ja.properrties

# 個別メッセージ
Pattern.invoice.phoneNumber = {0}は、半角の数字かハイフンで入力してください(例:03-1234-5678)
min.invoice.price={0}は{1}円以上の値を入力してください

# 共通メッセージ
NotBlank = {0}を入力してください
NotNull = {0}を入力してください
Size = {0}は{2}文字以上、{1}文字以下で入力してください。
min ={0}は{1}以上の値を入力してください。

# typeMismatch:個別メッセージ
typemismatch.invoice.price = {0}が不正な値です。
typeMismatch.invoice.paymentDealine={0}は"2020-01-01"形式で入力してください。

 ・ValidationMessages.properties


# Individual messages
Pattern.invoice.phoneNumber ={0} must bea half-width numver or hyphen (e.g.03-1234-5678)
Min.invoice.price = {0} must be greater than or equal to {1} JPY
# Common messages
NotBlank = {0} is required
NotNull = {0} is required
Size = {0} must be between {2} and {1} characters
Min = {0} must be greater than or equal to {1}

# typeMismatch: Individual messages
typeMismatch.invoice.price = {0} is incorrect
typeMismatch.invoice.paymentDeadline = {0} must be in "2020-01-01" format

確認

登録画面が開くか確認
課題16.png

空白で登録ボタン押下でエラーメッセージ表示
課題19.png

登録ボタン押下後登録できているか確認
課題17.png

課題18.png

以上

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?