LoginSignup
ak_soc4747
@ak_soc4747 (Ayamichi Kajiya)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

SpringBoot エラーメッセージが表示されない [Validation][Gradle]

解決したいこと

SpringBoot(Gradle Eclipse)で社員管理システムを作成しています。
新規登録画面にて入力チェック(@NotNull etc..)のValidationをつけていますが、うまくHTMLのほうにエラーメッセージが表示されません。
エラーメッセージはなく、System.out.Println(bindingresult)にてコンソールに表示されている画像しかありません。
ご教示お願いいただけたら幸いです。

発生している問題・エラー

コンソール

org.springframework.validation.BeanPropertyBindingResult: 5 errors
Field error in object 'employeesForm' on field 'emp_joinday': rejected value []; codes [typeMismatch.employeesForm.emp_joinday,typeMismatch.emp_joinday,typeMismatch.java.sql.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employeesForm.emp_joinday,emp_joinday]; arguments []; default message [emp_joinday]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.sql.Date' for property 'emp_joinday'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@javax.validation.constraints.NotNull java.sql.Date] for value ''; nested exception is java.lang.IllegalArgumentException]
Field error in object 'employeesForm' on field 'gender': rejected value [null]; codes [NotNull.employeesForm.gender,NotNull.gender,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employeesForm.gender,gender]; arguments []; default message [gender]]; default message [null は許可されていません]
Field error in object 'employeesForm' on field 'user_name': rejected value []; codes [NotEmpty.employeesForm.user_name,NotEmpty.user_name,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employeesForm.user_name,user_name]; arguments []; default message [user_name]]; default message [省略することはできません]
Field error in object 'employeesForm' on field 'emp_mail': rejected value []; codes [NotEmpty.employeesForm.emp_mail,NotEmpty.emp_mail,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employeesForm.emp_mail,emp_mail]; arguments []; default message [emp_mail]]; default message [省略することはできません]
Field error in object 'employeesForm' on field 'emp_phone': rejected value []; codes [NotEmpty.employeesForm.emp_phone,NotEmpty.emp_phone,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employeesForm.emp_phone,emp_phone]; arguments []; default message [emp_phone]]; default message [省略することはできません]

該当するソースコード

bulud.gradle
plugins {
	id 'org.springframework.boot' version '2.5.12'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
}

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

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-jdbc'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation "mysql:mysql-connector-java:8.0.20"
    implementation 'org.springframework.boot:spring-boot-starter-validation'

	implementation 'org.projectlombok:lombok:1.18.22'
    implementation 'org.webjars:jquery:3.5.1'
    implementation 'org.webjars:bootstrap:4.5.3'
    implementation 'org.webjars:webjars-locator:0.40'
    implementation 'org.springframework.boot:spring-boot-starter-validation:2.6.5'
    implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.0.0'

	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	runtimeOnly 'mysql:mysql-connector-java'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
	useJUnitPlatform()
}


コントローラークラス

EmployeesController.java
// 新規登録画面
	@GetMapping("new")
	public String getNew(@ModelAttribute EmployeesForm eForm, Model model) {
		model.addAttribute("eForm", eForm);
		return "emp/new";
	}
	@PostMapping("new")
	public String postNew(@Validated(GroupOrder.class) @ModelAttribute EmployeesForm eForm,
			BindingResult result, Model model) {
		// 入力チェック
		if (result.hasErrors()) {
			System.out.println(result);
			//入力画面に戻る
			return getNew(eForm, model);
           //↑↑↑ new.htmlに戻すverもやったが不可
		}else {
			// チェック後データベースに保存・送信
			employeesService.save(eForm);
			model.addAttribute("eForm", eForm);
		}
		return "redirect:/view";
	}

表示用のHTML

new.html
<!-- 省略 -->
<body>
	<form method="post" th:action="@{/new}" th:object="${eForm}">
		<h2 style="margin-left: 5%;">ユーザー登録</h2>
		<div class="form-group">
			<table class="table" border="1">
				<tr>
				  <th width="20%"><label for="emp_id" th:text="#{emp_id}"></label></th>
			      <td style=""><input type="text" class="form-control" 
                        th:field="*{emp_id}" th:errorclass="is-invalid" />
						<p class="invalid-feedback" th:errors="*{emp_id}"></p>
					</td>
				</tr>
				<tr>
				  <th scope="col"><label for="password" th:text="#{password}"></label></th>
				  <td scope="col"><input type="text" class="form-control"	
                        th:field="*{password}" th:errorclass="is-invalid" />
						<p class="invalid-feedback" th:errors="*{password}"></p>
				</tr>
				<tr>
				  <th scope="col"><label for="user_name" th:text="#{user_name}"></label></th>
				  <td scope="col"><input type="text" class="form-control"
                        th:field="*{user_name}" th:errorclass="is-invalid" />
						<p class="invalid-feedback" th:errors="*{user_name}"></p>
					</td>
				</tr>
				<tr>
					<th scope="col"><label for="emp_mail" th:text="#{emp_mail}"></label></th>
					<td scope="col"><input type="text" class="form-control" 
                        th:field="*{emp_mail}" th:errorclass="is-invalid" />
						<p class="invalid-feedback" th:errors="*{emp_mail}"></p>
					</td>
				</tr>
				<tr>
				  <th scope="col"><label for="emp_phone" th:text="#{emp_phone}"></label></th>
				  <td scope="col"><input type="text" class="form-control"
						th:field="*{emp_phone}" th:errorclass="is-invalid" />
						<p class="invalid-feedback" th:errors="*{emp_phone}"></p>
					</td>
				</tr>
				<tr>
					<th scope="col"><label for="emp_joinDay"
						th:text="#{emp_joinday}"></label></th>
					<td scope="col"><input type="date" class="form-control"
						th:field="*{emp_joinday}" th:errorclass="is-invalid" />
						<p class="invalid-feedback" th:errors="*{emp_joinday}"></p>
					</td>
				</tr>
				<tr>
					<th scope="col"><label for="gender" th:text="#{gender}"></label></th>
					<td scope="col" align="left">
						<div class="form-check" style="display: inline-block;">
							<input class="form-check-input" type="radio" name="gender"
								id="men" value="男性" th:field="*{gender}"
								th:errorclass="is-invalid"> <label
								class="form-check-label" for="men" th:text="#{men}"></label>
						</div>
						<div class="form-check" style="display: inline-block;"
							align="left">
							<input class="form-check-input" type="radio" name="gender"
								id="female" value="女性" th:field="*{gender}" 
                                  th:errorclass="is-invalid" checked>
								<label class="form-check-label" for="female" 
                                     th:text="#{female}"> 
                                 </label>
						</div>
						<p class="invalid-feedback" th:errors="*{gender}"></p>
					</td>
				</tr>
			</table>
		</div>
		<div align="center" style="margin-left: 40%;">
			<input type="submit" value="新規" class="btn btn-primary" />
		</div>
	</form>
</body>
</html>

フォーム(Validationチェック)

EmployeesForm.java
import java.sql.Date;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

import org.hibernate.validator.constraints.Length;

import lombok.Data;
@Data
public class EmployeesForm {
	@NotNull(message = "省略することはできません",groups = ValidGroup1.class)
	private String emp_id;

	@NotNull(message = "省略することはできません" ,groups = ValidGroup1.class)
	@Length(min=6, max=100, groups = ValidGroup2.class )
	@Pattern(regexp ="^[a-zA-Z0-9]+$", groups = ValidGroup2.class,
              message ="使用できない文字が含まれています")
	private String password;

	@NotEmpty(message = "省略することはできません" ,groups = ValidGroup1.class)
	private String user_name;

	@NotEmpty(message = "省略することはできません" ,groups = ValidGroup1.class)
	@Email(groups = ValidGroup2.class, message = "mailFormatに従ってください")
	private String emp_mail;

	@NotEmpty(message = "省略することはできません" ,groups = ValidGroup1.class)
	@Pattern(regexp="^(070|080|090)-\\d{4}-\\d{4}$", groups = ValidGroup2.class,
             message = "携帯電話の形式ではありません")
	private String emp_phone;

	@NotNull(groups = ValidGroup2.class)
	private Date emp_joinday;
	
	@NotNull(groups = ValidGroup1.class)
	private String gender;
}
messages.properties
emp_id=社員番号
NotNull.emp_id={0}を入力してください
password=パスワード
NotEmpty.password={0}を入力してください
user_name=氏名
emp_mail=メールアドレス
emp_phone=電話番号
emp_joinday=入社年月日
gender=性別
men=男性
female=女性
ValidationMessages.properties
typeMismatch.employeesForm.emp_id=省略することはできません
typeMismatch.employeesForm.emp_joinday=省略することはできません
typeMismatch.employeesForm.gender=省略することはできません

Email={0}はメールアドレス形式で入力してください
Length={0}は、{2}桁以上、{1}桁以下で入力してください
Pattern={0}は半角英数字で入力してください
NotNull={0}は必須入力です
min={0}は{1}以上を入力してください
max={0}は{1}以下を入力してください
application.properties
# messages
spring.messages.basename=i18n/messages,i18n/ValidationMessages

スクリーンショット 2022-04-28 174157.png

自分で試したこと

https://qiita.com/suema0331/items/9b138e5aa2b46009694e
https://macchinetta.github.io/server-guideline-thymeleaf/current/ja/ArchitectureInDetail/WebApplicationDetail/Validation.html
https://qiita.com/NagaokaKenichi/items/65d0e07151292968d67f
Spring解体新書2

他サイトも参考にしました。
Formのmessageとmessages.propertiesでどちらか一つでもエラーメッセージが反映できるようmessages.propertiesにもValidation用メッセージを設定しています。
何かコード、ビルドのほうで足りないところはありますでしょうか。
GradleのSpringBootは初めてなので、足りないところがあればご教示お願いいたします。

1

1Answer

SpringBootでは@Validatedが付与されたインスタンスの名前を親としてValidationのエラーが付与されるため、formを以下のように修正すれば解決すると思います。

<form method="post" th:action="@{/new}" th:object="${employeesForm}">

参考にした記事

2

Comments

  1. @ak_soc4747

    Questioner
    回答ありがとうございます!
    解決いたしました!感謝です。

Your answer might help someone💌