たなかのJava日記

どんなことをやったか(学んだか)、どこで詰まったか(わからなかったか)、どこで工夫したかの記録です。

【Spring Boot】登録ボタン押下するとエラーになる件について

前回までで、タスクの一覧表示とタスクの登録ができるようになったのですが、
作成した直後、登録ボタンを押下するとエラーになってしまいました。


自分の思考のクセや、ミスをしがちなパターンかもしれないので
サンプルとして記しておきます。


今回作成したのが、hello.htmlとHomeControllerクラスになります。
この中から間違いを探しました。


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>タスク管理アプリケーション</title>
</head>

    <body>
        <h1>タスク管理アプリケーション</h1>
    
        <div class="task_form">
            <h2>タスクの登録</h2>
    
            <form action="/add">
                <label>タスク</label>
                <input name="task" type="text" />
                <label>期限</label>
                <input name="deadline" type="date" />
                <input type="submit" value="登録" />
            </form>
        </div>
    
        <div class="tasklist">
            <h2>現在のタスクの一覧</h2>
            <table border="1" style="border-collapse:collapse;">
                <thead>
                    <tr><th class="hidden">ID</th><th>タスク</th><th>期限</th><th>状態</th></tr>
                </thead>
    
                <tbody>
                    <tr th:each="task :${taskList}">
                        <td class="hidden" th:text="${task.id}"></td>
                        <td th:text="${task.task}"></td>
                        <td width="100px" th:text="&{task.deadline}"></td>
                        <td width="50px" th:text="${task.done} ? '完了': '未完了'"></td>
                    </tr>
                </tbody>
            </table>
        </div>
    
    </body>
</html>
package jp.gihyo.projava.tasklist;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.ArrayList;
import java.util.List;

@Controller
public class HomeController {
    record TaskItem(String id, String task, String deadline, boolean done) {}
    private List<HomeRestController.TaskItem> taskItems = new ArrayList<>();

    @GetMapping("/list")
    String listItems(Model model) {
        model.addAttribute("taskList", taskItems);
        return "home";
    }

    @GetMapping("/add")
    String addItem(@RequestParam("task") String task,
                   @RequestParam("deadline") String deadline) {
        String id = UUID.randomUUID().toString().substring(0, 8);
        TaskItem item = new TaskItem(id, task, deadline, false);
        taskItems.add(item);

        return "redirect:/list";
    }
}


hello.htmlでは、
&{task.deadline}が間違っています。


正しくは、${task.deadline}です。
&のせいで変数と認識されていなかったわけです。


HomeControllerクラスでは、
private List taskItems = new ArrayList<>();
が間違っています。


正しくは、
private List taskItems = new ArrayList<>();
となります。


以前作成したクラスから同様のListをコピペで持ってきた際に、
コピー元のクラスを型に指定しまったようです。


こういった思い込みがバグの原因になるので気を付けなけばなりません。


追記
登録したタスクが正しく表示されない場合は、まずはHTMLテンプレートとの連携に使用している
属性のキーを間違えていないかを確認するのが良いとのことです。

今回の例だと、Java側で使用している属性のキー"taskList"と
HTMLテンプレート側で使用している${taskList}が一致していないことです。