1
0

Thymeleafのバリデーションエラー時にIllegalStateException発生した

Posted at

解決法

th:objectに入れる変数を、バリデートを設定しているクラス名(キャメルケース)に合わせる

事象

  • 以下1~3を実装し、バリデートにかかる状態で「登録」を押すと例外が発生してしまった
  • 例外は java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'newForm' available as request attribute(newFormがダメなようなエラー)

修正前の実装

1. Formクラス

  • nameに「1以下のサイズを許可」するバリデートを設定
@Data
public class SampleForm {
	@Size(max = 1)
	private String name;
}

2. Controllerクラス

  • 1.のFormクラスを使って画面表示と入力内容の取得をしている
  • Formクラスは「newForm」という属性名になっている
	//新規登録画面を表示
	@GetMapping("/sample")
	public String displayadd(Model model) {
		model.addAttribute("newForm", new SampleForm());

		return "common/sample";
	}

	//新規登録処理
	@PostMapping("/sample/create")
	public String createUser(@Validated SampleForm newForm, BindingResult result, Model model) {
		if (result.hasErrors()) {
            // バリデートにかかったら元の画面を表示
			return "common/sample";
		}

		//	新規登録する処理を入れる
		return "complete";
	}

3. 新規登録画面html(thymeleaf)

<form th:object="${newForm}">
	<div>
		<input type="text" th:field="*{name}">
		<div th:errors="*{name}"></div>
	</div>
	<input type="submit" th:formaction="@{/sample/create}" th:formmethod="post" value="登録">
</form>

修正方法

  • 以下のように修正することで正常に動くようになった
    • 「3.新規登録画面html」のth:object="${newForm}"th:object="${sampleForm}"に修正
    • 「2.Controllerクラス」のnewFormsampleFormに修正
  • ★別解
    • 「3.新規登録画面html」のエラーメッセージを出す部分を、以下の通り「sampleFormというオブジェクトからとる」「sampleForm」がない時は表示しない、となる変更をす
      <div th:if="${sampleForm}" th:errors="${sampleForm.name}"></div>
    • 「2.Controllerクラス」新規登録処理のif内に、model.addAttribute("newForm", newForm);を追加

事象整理

  • th.errorsの値は、${バリデート設定しているFormクラスの名前(キャメルケース).フィールド名}にする必要がある。
  • 別解の「2.Controllerクラス」のみを対応すると、例外は出ないがエラーメッセージも出ない状態になった
  • 「★別解」のときに、th:if="${sampleForm}"を入れないと、新規登録画面表示時に例外が発生する。(修正前の登録押下時の例外と同じ種類で、sampleFormでダメなようなエラー)
  • 「★別解」で「2.Controllerクラス」のほうの修正がないと、修正前と同じエラーが同じタイミングで発生する

考察

  • バリデーションエラーにかかるとき、BindingResultか何かで
    model.addAttribute("{Formクラスの名前(キャメルケース)}", {入力情報やバリデートエラーメッセージ});
    的なのが自動で設定されているのではないか?と思った
  • 画面表示時に渡しているmodel.addAttributeの属性名が「Formクラス名(キャメルケース)」と等しければ、登録処理から帰って来る時と同じ属性名になるので、入力値が保持されるしエラーメッセージもちゃんと出る
1
0
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
1
0