質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.59%

spring boot でのthymeleafでの値の受渡しで例外が発生する

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 8,424

kinu221

score 24

前提・実現したいこと

spring bootでCRUDシステムを作っていますが、下記の例外が発生しているのでトラブルシュートをしたい。

発生している問題・エラーメッセージ

An error happened during template parsing (template: "class path resource [templates/persons/new.html]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/persons/new.html]")
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "#fields.hasErrors('name')" (template: "persons/new" - line 11, col 33)
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "#fields.hasErrors('name')" (template: "persons/new" - line 11, col 33)
Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'person' available as request attribute

該当のソースコード

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="layout">
<head>
    <title>New Person</title>
</head>
<body>
    <div class="container" layout:fragment="content">
        <h1>New Person</h1>
      <form th:action="@{/persons}" th:method="post" th:object="${person}">
        <div class="form-group" th:classappend="${#fields.hasErrors('name')}? has-error">
          <label class="control-label">名前</label>
          <input class="form-control" type="text" th:field="*{name}" />
          <span class="text-danger" th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></span>
        </div>
        <div class="form-group" th:classappend="${#fields.hasErrors('age')}? has-error">
          <label class="control-label">年齢</label>
          <input class="form-control" type="number" th:field="*{age}" />
          <span class="text-danger" th:if="${#fields.hasErrors('age')}" th:errors="*{age}"></span>
        </div>
        <div class="form-group" th:classappend="${#fields.hasErrors('belong')}? has-error">
          <label class="control-label">所属</label>
          <input class="form-control" type="text" th:field="*{belong}" />
          <span class="text-danger" th:if="${#fields.hasErrors('belong')}" th:errors="*{belong}"></span>
        </div>
        <div class="form-group" th:classappend="${#fields.hasErrors('workplace')}? has-error">
          <label class="control-label">勤務地</label>
          <input class="form-control" type="text" th:field="*{workplace}" />
          <span class="text-danger" th:if="${#fields.hasErrors('workplace')}" th:errors="*{workplace}"></span>
        </div>
        <button class="btn btn-default" type="submit">作成</button>
      </form>
        <div class="pull-right">
            <a class="btn btn-link" href="/persons">一覧画面へ</a>
        </div>
    </div>
</body>
</html>
package com.example.person.controller;



import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.person.entity.PersonEntity;
import com.example.person.service.PersonService;



@Controller
@RequestMapping("/persons")
public class PersonController {
    @Autowired
    private PersonService personService;

    @GetMapping
    public String index(Model model) {
        List<PersonEntity> person = personService.findAll();
        model.addAttribute("person", person);
        return "persons/index";
    }

    @GetMapping("new")
    public String newPerson(Model model) {
        PersonEntity person = new PersonEntity();
        model.addAttribute("person", person);
        return "persons/new";
    }

    @GetMapping("{id}/edit")
    public String edit(@PathVariable int id, Model model) {
        PersonEntity person = personService.findOne(id);
        model.addAttribute("person",person);
        return "persons/edit";
    }

    @GetMapping("{id}")
    public String show(@PathVariable int id, Model model) {
        PersonEntity person = personService.findOne(id);
        model.addAttribute("person", person);
        return "persons/show";
    }

    @PostMapping
    public String create(@ModelAttribute PersonEntity person, BindingResult bindingResult) {
        if(bindingResult.hasErrors()) return "persons/new";
        personService.save(person);
        return "redirect:/persons";
    }

    @PutMapping("{id}")
    public String update(@PathVariable int id, @Valid @ModelAttribute PersonEntity person, BindingResult bindingResult) {
        if(bindingResult.hasErrors()) return "persons/edit";
        person.setId(id);
        personService.save(person);
        return "redirect:/persons";
    }

    @DeleteMapping("{id}")
    public String destroy(@PathVariable int id) {
        personService.delete(id);
        return "redirect:/persons";
    }
}

試したこと

Exception evaluating SpringEL expression: "#fields.hasErrors('name')" (template: "persons/new" - line 11, col 33)の記載がありましたのでhttps://teratail.com/questions/156753を参考に
"#fields.hasErrors('name')"やth:objectの見直しを行いました。

補足情報(FW/ツールのバージョンなど)

STS
phpmyadmin

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • asahina1979

    2019/05/08 13:27

    person.java の全文(コメントは削除可)を追記してください

    キャンセル

  • kinu221

    2019/05/08 20:18

    person.javaはentityクラスを追記すれば良いですか?

    キャンセル

回答 2

+1

スタックトレースを全文読むと、PersonEntityのフィールドに関するアクセサ(=getterメソッド)がないのでThymeleafから出力できない、かと思います。

Caused by: org.springframework.beans.NotReadablePropertyException: 
Invalid property 'name' of bean class [****.PersonEntity]: 
Bean property 'name' is not readable 
or has an invalid getter method: 
Does the return type of the getter match the parameter type of the setter?

少なくとも、Thymeleafで表示しているPersonEntityの内容を出力するHTMLにて、name、age、belong、workplace が定義されていて、かつ それぞれのフィールドに対してすべてgetメソッドが定義されていなければなりません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/08 20:16

    ご回答有難うございます。
    Entityクラスにgetter、setterを全てのフィールドに対して用意しています。

    キャンセル

  • 2019/05/08 21:10

    自己解決しました。有難うございました

    キャンセル

  • 2019/05/08 21:11

    そうであれば、/persons/new で表示しているときは表示されるかと思いますが、別のリクエストでしょうか。

    キャンセル

check解決した方法

0

クラスパスの見直しを行うと解決しました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る