LoginSignup
23
30

More than 5 years have passed since last update.

Spring-Boot でControllerからThymleafへ、Formクラスを受け渡す

Posted at

目的

Thymeleafで表示されているテンプレートへ、Controllerから、オブジェクトを受け渡す時の最小構成

前提

  • Thymleafの導入は済んでいること
  • Spring-Boot 1.5.1.RELEASE

手順

Formクラスですること

  • Formクラスと言っているのは、ripositoryではなく、普通のjavaクラスに値を乗せてコントローラ、ビュー間でやり取りをする時受け渡すオブジェクトのクラス

  • javaクラスは、POJOなクラスでいい

  • GetterとSetterが必ず必要

  • Lanbokが使える。 @Dataをつけるだけでアクセッサはオーケー

ContractListForm.java
package com.contract.web;

import lombok.Data;

@Data
public class ContractListForm{
    private String anken_kbn; // 案件区分
    private String anken_name; // 案件名 
}

Controllerですること

  • Formクラスのインスタンスを生成し、コントローラでもつ
  • 画面へFormクラスのインスタンスを渡す

  • 先ほどのクラスを、@ModelAttributeアノテーションのついたメソッドで生成
    このアノテーション付きのメソッドは、@RequestMapping付きのメソッドが呼ばれた時(リクエストを受けた時)に自動的に呼び出されます
    このアノテーションのついたメソッドで、フォームクラスのインスタンスを生成します
    ここで作成されたインスタンスはリクエストスコープに登録されます

  • @RequestMappingメソッドで、画面へオブジェクトを渡します。
    addObjectメソッドで、最初の引数で画面側でのインスタンス名を定義します、画面からはこの名前で受け取ります
    第2引数で実際に渡すオブジェクトを渡します

ContractListsController
    @ModelAttribute
    ContractListForm setUpForm() {
        return new ContractListForm();
    }

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView index(ModelAndView mav) {
        mav.setViewName("index");
        mav.addObject("contractListF", new ContractListForm()); // 検索フォーム用インスタンス
        return mav;

    }

テンプレートファイルですること

  • まずformタグでオブジェクトを受け取ります
index.html
<form method="post" action="/Contract/search" th:object="${contractListF}">
  • th:object="${contractListF}"
  • th:objectタグで$に続いてaddObjectで指定した名前を受け取ります、ここにインスタンスが入ってくる
index.html
<input type="text" th:field="*{anken_kbn}" class="form-control" aria-describedby="basic-addon2"></input>
<input type="text" th:field="*{anken_name}" class="form-control" aria-describedby="basic-addon2"></input>
  • その中のフィールドは
  • th:field="*{anken_name}"
  • th:fieldタグで受け取り、こちらは*{ アスタリスクのカッコでうけとる。フィールド名をそのままかく

このへんの設定ができていないと、以下のようなエラーが発生します
- アクセッサの不備を出していますが、実際には上のルールができていない時にも同じエラーメッセージが出ます。


org.springframework.beans.NotReadablePropertyException: Invalid property 'contractListForm' of bean class [com.contract.web.ContractListForm]: Bean property 'contractListForm' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?

混乱したポイント

  • 自分が混同したのは、repositoryのオブジェクトを受け取るときは、以下のような書き方をします
index.html
<tr th:each="obj : ${contractList}">
                <td th:text="${obj.anken_kbn}"></td>
                <td th:text="${obj.anken_mei}"></td>

ここへ送っているコントローラのリクエストメソッドは、実はさっきのと同じで、本当はこうなっていました

ContractListsController.java
@RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView index(ModelAndView mav) {
        mav.setViewName("index");
        Iterable<TMitsumoriHdrEntity> hdrEntityList = hdrDao.findAll();
        mav.addObject("contractList", hdrEntityList);
        mav.addObject("contractListF", new ContractListForm()); // 検索フォーム用インスタンス
        return mav;

    }
  • ここで、daoから取得したEntityのリストをcontractListという名前で以下のように渡しています。
mav.addObject("contractList", hdrEntityList);
  • この場合、リストでEntityが受け取られていて、それをループで取得します、その場合は
<tr th:each="obj : ${contractList}">
  • th:eachで受け取って、変数 : ${でインスタンス名}
  • その変数に対して
 <td th:text="${obj.anken_kbn}"></td>
  • 値を表示する th:text に 変数名.フィールド名 
  • という書き方をします

まとめると

インスタンス インスタンスの取り方 フィールドの取り方
Form(POJO)のオブジェクト th:object="${contractListF}" th:field="*{anken_kbn}
Entityのオブジェクト th:each="obj : ${contractList}" th:text="${obj.anken_kbn}"
23
30
1

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
23
30