前提・実現したいこと
Spring Boot を用いてJavaによるウェブページ作成を行っています
Thymeleaf を用いているJavaのバリデーションチェックで、元の値をhtmlの入力フォームに表示させつつ新たに入力された値が適切かどうかを判定したいです
ファイル構成は以下の画像のようになっております(画面からは見切れていますがtemplatesフォルダ内にhtml一式が格納されています)
発生している問題・エラーメッセージ
発生している問題
コンパイルエラーにはなっていないが、update.htmlにおいてUpdateForm.javaで定義したエラー条件をはじいてくれない
以下、update.htmlです(bookに書籍情報一式が格納)
html
1update.html 2<!DOCTYPE html> 3<html> 4<head> 5<meta charset="UTF-8"> 6<title>書籍を編集するよ</title> 7</head> 8<body> 9 <table> 10 <tr th:if="${validationError}" th:each="error : ${validationError}"> 11 <td style="color: red;" th:text="${error}"></td> 12 </tr> 13</table> 14 15<form th:method="POST" th:action=@{/updateResult} onSubmit="return MoveCheck()" th:object="${updateForm}"> 16書籍ID(自動入力) <p style="display:inline;" th:text="${book.bookID}"></p><br> 17<br> 18タイトル: <input type="text" th:value="${book.title}" placeholder="" th:name="title" th:id="title" > 19<br> 20著者: <input type="text" th:value="${book.writer}" placeholder="" name="writer"> 21<br> 22出版社: <input type="text" th:value="${publisher.publisherName}" placeholder="" name="publisher"> 23<br> 24価格: <input type="number" th:value="${book.price}" placeholder="" name="price"> 25<br> 26購入日: <input type="date" th:value="${book.bought}" placeholder="" name="bought" min="1900-01-01" max="2021-12-31"> 27<br> 28書籍管理部門: <input type="text" th:value="${department.deptName}" placeholder="" name="mngDept"> 29<br> 30更新日(自動入力)<p style="display:inline;" th:text="${#calendars.format(#calendars.createNowForTimeZone('Asia/Tokyo'), 'yyyy-MM-dd HH:mm:ss')}"></p><br> 31<br> 32更新者(自動入力) <p style="display:inline;" th:text="${user.name}"></p><br> 33<br> 34更新者部署(自動入力) <p style="display:inline;" th:text="${department.deptName}"></p><br> 35<br> 36 37<button type="button" onclick="history.back()">戻る</button> 38 39<input type="hidden" name="bookID" th:value="${book.bookID}"> 40<input type="hidden" name="updated" th:value="${#calendars.format(#calendars.createNowForTimeZone('Asia/Tokyo'), 'yyyy-MM-dd HH:mm:ss')}"> 41<input type="hidden" name="userName" th:value="${user.name}"> 42<input type="hidden" name="updatorDept" th:value="${department.deptName}"> 43<input type="submit" value="更新する"> 44</form> 45 46<script> 47function MoveCheck() { 48 i省略 49} 50</script> 51</body> 52</html>
html画面部の表示はこのようになっております。(一部個人情報のため伏せさせていただきますが、ご了承ください)
以下、UpdateForm.javaです
Java
1字数制限のため**追記の方にまとめて記載**しました。そちらをご覧ください
MySQLの実行結果画像(一部個人情報のため伏せさせていただきますが、ご了承ください)
BOOKID:5 のように、title や writer が空欄でもはじかれずにデータベースへ登録されてしまいます
試したこと
https://ti-tomo-knowledge.hatenablog.com/entry/2018/06/14/162616
を参考にinputタグの中身をいじったりもしたのですが現状うまくいっておりません
該当のソースコード
入力フォームへと遷移する
Java
1@RequestMapping(value = "/update", method = RequestMethod.POST) 2 public String update( 3 @RequestParam(name = "bookID") int bookID, 4 Model model) { 5 if(loginSessionCheck() == false) { 6 return "index"; 7 } 8model.addAttribute("updateForm", new UpdateForm()); 9 10//更新対象となる書籍情報の取得 11//ここでは省略させていただきます 12 13return "update"; //update.htmlへ 14}
入力フォームから入力完了画面へと遷移する
ここで入力フォームにエラーが確認されたら再度入力フォームへ遷移する
Java
1 2 @RequestMapping(value = "/updateResult", method = RequestMethod.POST) 3 public String updateResult( 4 @Validated 5 @RequestParam(name = "updated") Timestamp updated, 6 @RequestParam(name = "bookID") int bookID, 7 @RequestParam(name = "title") String title, 8 @RequestParam(name = "writer") String writer, 9 @RequestParam(name = "publisher") String publisher, 10 @RequestParam(name = "price") int price, 11 @RequestParam(name = "bought") Date bought, 12 @RequestParam(name = "mngDept") String mngDept, 13 @RequestParam(name = "updatorDept") String updatorDept, 14 @RequestParam(name = "userName") String userName, 15 @ModelAttribute UpdateForm updateForm, 16 BindingResult result, 17 Model model) { 18 if(loginSessionCheck() == false) { 19 return "index"; 20 } 21 //エラー内容をリストに詰めてupdate画面側に返却します 22 System.out.println("result = " + result); 23 if (result.hasErrors() == true) { 24 List<String> errorList = new ArrayList<String>(); 25 for (ObjectError error : result.getAllErrors()) { 26 errorList.add(error.getDefaultMessage()); 27 } 28 model.addAttribute("validationError", errorList); 29 return "update"; 30 } 31 32 //書籍情報の更新作業を実施 33 //ここでは省略させていただきます 34 35 return "updateResult"; 36 }
補足情報(FW/ツールのバージョンなど)
Spring Boot 2.5.2
お手数ですがご教授お願い致します。
###追記
Contoroller部分、HTML部分, JavaのForm部分を以下のように書き換えたのですがうまく動きませんでした(例外スローされてしまう)。
Controller
JAVA
1@RequestMapping(value = "/updateResult", method = RequestMethod.POST) 2 public String updateResult( 3 /*リクエストパラメタ一式を削除*/ 4 @ModelAttribute 5 @Validated UpdateForm updateForm, 6 BindingResult result, 7 Model model) { 8 if(loginSessionCheck() == false) { 9 return "index"; 10 } 11 //エラー内容をリストに詰めてupdate画面側に返却します 12 System.out.println("result = " + result); 13 if (result.hasErrors() == true) { 14 List<String> errorList = new ArrayList<String>(); 15 for (ObjectError error : result.getAllErrors()) { 16 errorList.add(error.getDefaultMessage()); 17 } 18 model.addAttribute("validationError", errorList); 19 return "update"; 20 } 21 22 /*書籍更新処理 ここでは省略させていただきます*/ 23 24 return "updateResult"; 25 }
HTML
HTML
1 2 <table> 3 <tr th:if="${validationError}" th:each="error : ${validationError}"> 4 <td style="color: red;" th:text="${error}"></td> 5 </tr> 6</table> 7 8<form th:method="POST" th:action=@{/updateResult} onSubmit="return MoveCheck()" th:object="${updateForm}"> 9書籍ID(自動入力) <p style="display:inline;" th:text="${book.bookID}"></p><br> 10<br> 11タイトル: <input type="text" th:name="title" th:id="title" th:value="${book.title}" placeholder=""> 12<br> 13著者: <input type="text" th:value="${book.writer}" placeholder="" th:name="writer" th:id="writer"> 14<br> 15出版社: <input type="text" th:value="${publisher.publisherName}" placeholder="" th:name="publisher" th:id="publisherr"> 16<br> 17価格: <input type="number" th:value="${book.price}" placeholder="" th:name="price" th:id="price"> 18<br> 19購入日: <input type="date" th:value="${book.bought}" placeholder="" th:name="bought" th:id="bought" min="1900-01-01" max="2021-12-31"> 20<br> 21書籍管理部門: <input type="text" th:value="${department.deptName}" placeholder="" th:name="mngDept" th:id="mngDept"> 22<br> 23更新日(自動入力)<p style="display:inline;" th:name="Timestamp" th:id="Timestamp" th:text="${#calendars.format(#calendars.createNowForTimeZone('Asia/Tokyo'), 'yyyy-MM-dd HH:mm:ss')}"></p><br> 24<br> 25更新者(自動入力) <p style="display:inline;" th:name="userName" th:id="userName" th:text="${user.name}"></p><br> 26<br> 27更新者部署(自動入力) <p style="display:inline;" th:name="updatorDept" th:id="tupdatorDept" th:text="${department.deptName}"></p><br> 28<br> 29 30<button type="button" onclick="history.back()">戻る</button> 31<input type="hidden" th:id="bookID" th:name="bookID" th:value="${book.bookID}"> 32 33<input type="submit" value="更新する"> 34</form> 35 36<script> 37function MoveCheck() { 38 省略 39} 40
FORM部分
JAVA
1import java.io.Serializable; 2import java.sql.Timestamp; 3import java.util.Date; 4 5import javax.validation.constraints.Min; 6import javax.validation.constraints.NotBlank; 7import javax.validation.constraints.NotEmpty; 8import javax.validation.constraints.NotNull; 9import javax.validation.constraints.Size; 10 11 12public class UpdateForm implements Serializable{ 13 14 @NotBlank(message = "タイトルを入力してね") 15 @Size(min = 1, max = 200, message = "タイトルは1文字以上200文字以内で入力してください") 16 private String title; 17 18 @NotEmpty(message = "著者を入力してね") 19 @Size(min = 1, max = 200, message = "著者は1文字以上200文字以内で入力してください") 20 private String writer; 21 22 @NotEmpty(message = "出版社を入力してね") 23 @Size(min = 1, max = 200, message = "出版社は1文字以上200文字以内で入力してください") 24 private String publisher; 25 26 @NotNull(message = "値段を入力してね") 27 @Min(value = 10, message = "{value}以上の値を設定してください") 28 private Integer price; 29 30 @NotNull(message = "購入年月日を入力してね") 31 private Date bought; 32 33 @NotEmpty(message = "管理部署を入力してね") 34 private String mngDept; 35 36 private String updatorDept; 37 38 private String userName; 39 40 private int bookID; 41 42 private Timestamp updated; 43 44 /* getter/setter は省略させていただきます */ 45}
エラー文 必要そうな部分のみ抜粋
(boughtを String から Date に変換できない、と15行目のbookIDがおかしいという指摘?)
Field error in object 'updateForm' on field 'bought': rejected value [2020-12-13]; codes [typeMismatch.updateForm.bought,typeMismatch.bought,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [updateForm.bought,bought]; arguments []; default message [bought]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'bought'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@javax.validation.constraints.NotNull java.util.Date] for value '2020-12-13'; nested exception is java.lang.IllegalArgumentException] [2m2021-07-23 20:57:28.304[0;39m [31mERROR[0;39m [35m18044[0;39m [2m---[0;39m [2m[nio-8082-exec-5][0;39m [36morg.thymeleaf.TemplateEngine [0;39m [2m:[0;39m [THYMELEAF][http-nio-8082-exec-5] Exception processing template "update": Exception evaluating SpringEL expression: "book.bookID" (template: "update" - line 15, col 39) org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "book.bookID" (template: "update" - line 15, col 39)
2つ目のエラーのbookID部分がいまいち理解できておりません・・
回答2件
あなたの回答
tips
プレビュー