実現したいこと
SpringのThymeleaf を使って、お問い合わせフォームを作ってPOST送信し、確認画面を表示させたいです。
発生している問題・分からないこと
サンプルサイトを参考にフォームを作成したのですが、inputタグに「th:field="{...}"」等を入れると、「500エラー」が出て、表示出来なくなります。
th:field="{...}"関連の部分をなくすとHTMLは表示されます。
エラーメッセージ
error
1This application has no explicit mapping for /error, so you are seeing this as a fallback. 2 3Thu Jan 25 10:42:11 JST 2024 4There was an unexpected error (type=Internal Server Error, status=500). 5An error happened during template parsing (template: "class path resource [templates//form.html]") 6org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates//work3/form.html]") 7 at 8 (略) 9Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring6.processor.SpringInputGeneralFieldTagProcessor' (template: "/work3/form" - line 86, col 69)
該当のソースコード
html
1<!DOCTYPE html> 2<html lang="ja" xmlns:th="https://www.thymeleaf.org"> 3 4<head> 5 <meta charset="UTF-8"> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 8 <title>Sample Cafe</title> 9 <meta name="description" content="コーヒーショップのサンプルサイトです。"> 10 <!-- reset.css destyle --> 11 <link rel="stylesheet" th:href="@{../css/work3/reboot.min.css}" /> 12 <!-- custom.css destyle --> 13 <link rel="stylesheet" th:href="@{../css/work3/work3.css}"> 14 <link rel="stylesheet" th:href="@{../css/work3/form.css}"> 15 16</head> 17 18<body> 19 <header class="header"> 20 <a th:href="@{./index}"> 21 <h1 class="header-logo">Sample Cafe</h1> 22 </a> 23 <!--バーガーメニューボタン--> 24 <button id="hamburger" class="hamburger" aria-label="メニューを開く"> 25 <span class="hamburger_line" aria-hidden="true"></span> 26 </button> 27 <!--グローバルナビ--> 28 <nav id="gnav" class="gnav" aria-label="メインメニュー"> 29 <ul class="gnav-list"> 30 <li class="gnav-item"> 31 <a href="#" class="gnav-link">Home</a> 32 </li> 33 <li class="gnav-item"> 34 <a href="#" class="gnav-link">service</a> 35 </li> 36 <li class="gnav-item"> 37 <a href="#" class="gnav-link">products</a> 38 </li> 39 <li class="gnav-item"> 40 <a href="#" class="gnav-link">company</a> 41 </li> 42 <li class="gnav-item"> 43 <a href="#" class="gnav-link">recruit</a> 44 </li> 45 <li class="gnav-item"> 46 <a href="#" class="gnav-link">contact</a> 47 </li> 48 </ul> 49 </nav> 50 </header> 51 <div class="main"> 52 <div class="page-header"> 53 <h1 class="page-title"> 54 お問い合わせ 55 </h1> 56 </div> 57 58 <nav class="breadcrumb" aria-label="パンくずナビゲーション"> 59 <ol class="breadcrumb-list"> 60 <li class="breadcrumb-item"><a th:href="@{/work3/index}">ホーム</a></li> 61 <li class="breadcrumb-item"><a href="#" aria-current="page">お問い合わせ</a></li> 62 </ol> 63 </nav> 64 <main> 65 <div class="form-container"> 66 <h2>お問い合について</h2> 67 <p> 68 通常、3営業日以内に担当者よりご連絡差し上げます。<br /> 69 お急ぎの場合はお電話にてご連絡下さい。(TEL: 03-1234-5678 平日9:00〜18:00) 70 </p> 71 72 <!--お問い合わせフォーム--> 73 <h2>お問い合フォーム</h2> 74 75 <form action="#" method="POST" id="form" th:action="@{/work3/result}" th:object="${ContactForm}"> 76 <table class="form-table" role="presentation"> 77 78 <tr> 79 <th> 80 <label for="name" class="input-label"> 81 お名前 82 <span class="require" aria-hidden="true">必須</span> 83 </label> 84 </th> 85 <td> 86 <input type="text" id="name" name="name" placeholder="山田太郎" th:field="*{name}" required /> 87 </td> 88 </tr> 89 <tr> 90 <th> 91 <label for="email" class="input-label"> 92 メールアドレス 93 <span class="require" aria-hidden="true">必須</span> 94 </label> 95 </th> 96 <td> 97 <input type="text" id="email" name="email" placeholder="sample@sample.co.jp" th:field="*{email}" required /> 98 </td> 99 </tr> 100 <tr> 101 <th> 102 <label for="mail" class="input-label"> 103 電話番号 104 </label> 105 </th> 106 <td> 107 <input type="text" id="tell" name="tell" placeholder="03-1234-5678" th:field="*{tell}" /> 108 </td> 109 </tr> 110 <tr> 111 <th> 112 <div class="input-label"> 113 法人個人 114 <span class="require" aria-hidden="true">必須</span> 115 </div> 116 </th> 117 <td> 118 <div class="input-field"> 119 <ul class="radio-list"> 120 <li> 121 <label> 122 <input type="radio" name="attribute" value="法人" checked 123 th:field="*{attribute}" required /><span>法人</span> 124 </label> 125 </li> 126 <li> 127 <label> 128 <input type="radio" name="attribute" value="個人" 129 th:field="*{attribute}" required /><span>個人</span> 130 </label> 131 </li> 132 </ul> 133 </div> 134 </td> 135 </tr> 136 <tr> 137 <th> 138 <div class="input-label"> 139 <label for="contact-type"> 140 お問い合わせの種類 141 <span class="require" aria-hidden="true">必須</span> 142 </label> 143 </div> 144 </th> 145 <td> 146 <div class="input-field"> 147 <div class="select-wrap"> 148 <select name="type" id="contact_type" th:field="*{type}"> 149 <option value="" selected disabled>選択してください</option> 150 <option value="商品について">商品について</option> 151 <option value="返品・交換について">返品・交換について</option> 152 <option value="メディア取材について">メディア取材について</option> 153 <option value="その他のお問合せ">その他のお問合せ</option> 154 </select> 155 </div> 156 </div> 157 </td> 158 </tr> 159 <tr> 160 <th> 161 <label for="msg" class="input-label"> 162 お問い合わせ内容 163 <span class="require" aria-hidden="true">必須</span> 164 </label> 165 </th> 166 <td> 167 <div class="input-field"> 168 <textarea name="comment" id="comment" cols="30" rows="10" 169 th:field="*{comment}" required>お問い合わせ内容を記入してください。</textarea> 170 </div> 171 </td> 172 </tr> 173 </table> 174 175 <div class="privacy-box"> 176 <p id="privacy-description">「<a 177 th:href="@{/work3/privacy}">プライバシーポリシー</a>」をご確認いただき、個人情報の取扱いについて同意いただける場合は「同意する」を選択してください。 178 </p> 179 <div class="privacy-box-check"> 180 <label> 181 <input type="checkbox" id="agree" name="agree" value="同意します" required 182 aria-describedby="privacy-description"> 183 <span>個人情報保護方針に同意する</span> 184 </label> 185 </div> 186 </div> 187 <div class="button-center"> 188 <button id="submit" class="button button--action button--lg" disabled>入力内容を確認する</button> 189 </div> 190 </form> 191 </div> 192 </main> 193 </div> 194 195 <footer class="footer"> 196 <ul class="footer-menu"> 197 <li><a th:href="@{./law}">特定商取引法に関する表記</a></li> 198 <li><a th:href="@{./privacy}">プライバシーポリシー</a></li> 199 </ul> 200 <p class="footer-copyright"><small lang="en">© Sample All Rights Reserved.</small></p> 201 </footer> 202 203 <script src="https://code.jquery.com/jquery-3.6.0.min.js" 204 integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> 205 <script th:src="@{../js/work3/script.js}"></script> 206</body> 207 208</html>
java
1//WebControllers.java 2 3package com.example.demo.controller; 4 5import org.springframework.stereotype.Controller; 6import org.springframework.validation.BindingResult; 7import org.springframework.web.bind.annotation.GetMapping; 8import org.springframework.web.bind.annotation.PostMapping; 9import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 10import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 11 12import com.example.demo.form.ContactForm; 13 14import jakarta.validation.Valid; 15 16@Controller 17public class WebControllers implements WebMvcConfigurer { 18 19 @Override 20 public void addViewControllers(ViewControllerRegistry registry) { 21 registry.addViewController("/results").setViewName("results"); 22 } 23 24 @GetMapping("/work3/form") 25 public String ContactForm(ContactForm personForm) { 26 return "/work3/form"; 27 } 28 29 @PostMapping("/work3/form") 30 public String checkPersonInfo(@Valid ContactForm personForm, BindingResult bindingResult) { 31 32 if (bindingResult.hasErrors()) { 33 return "/work3/form"; 34 } 35 36 return "redirect:/results"; 37 } 38}
Java
1//ContactForm.java 2package com.example.demo.form; 3 4import jakarta.validation.constraints.Email; 5import jakarta.validation.constraints.NotNull; 6import jakarta.validation.constraints.Size; 7 8public class ContactForm { 9package com.example.demo.form; 10 11import jakarta.validation.constraints.Email; 12import jakarta.validation.constraints.NotNull; 13import jakarta.validation.constraints.Size; 14 15public class ContactForm { 16 17 @NotNull 18 @Size(min = 1, max = 400) 19 private String comment; 20 21 @NotNull 22 @Size(min = 1, max = 20) 23 private String name; 24 25 @NotNull 26 @Email(message = "Invalid E-mail Format") 27 private String email; 28 29 @NotNull 30 private String type; 31 32 private String tell; 33 34 @NotNull 35 private String attribute; 36 37 //name 38 public String getName() { 39 return name; 40 } 41 42 public void setName(String name) { 43 this.name = name; 44 } 45 46 //email 47 public String getEmail() { 48 return email; 49 } 50 51 public void setEmail(String email) { 52 this.email = email; 53 } 54 55 //type 56 public String getType() { 57 return type; 58 } 59 60 public void setType(String type) { 61 this.type = type; 62 } 63 64 //comment 65 public String getComment() { 66 return comment; 67 } 68 69 public void setComment(String comment) { 70 this.comment = comment; 71 } 72 73 //type 74 public String getTell() { 75 return tell; 76 } 77 78 public void setTell(String tell) { 79 this.tell = tell; 80 } 81 82 //type 83 public String getAttribute() { 84 return attribute; 85 } 86 87 public void setAttribute(String attribute) { 88 this.attribute = attribute; 89 } 90} 91 92
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
teratailやgoogleで色々と検索したのですが、解決には至りませんでした。
どこに誤りがあるのか教えてください。
補足
特になし
