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

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

新規登録して質問してみよう
ただいま回答率
85.49%
Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

2回答

27380閲覧

spring 入力チェックエラー

kiichan

総合スコア6

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2018/03/18 09:19

編集2018/03/18 10:19

springエラーチェックを実装しています。
初期値が表示される商品更新画面で、入力値が未入力の場合に
未入力の文字を表示させます。

そこで、下記のエラーがでました。

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'ItemForm' available as request attribute
調べると、 th:object="${ItemForm}"の値が使えていないなど考えらるみたいですが
formクラスのオブジェクトを使うのであっていると思うのですが

又、Exception evaluating SpringEL expression: "#fields.hasErrors('name')" と下記のHTML側で問題があるようで
調べています。

他に対処法として考えるべき点があれば教えていただきたいです。
初心者の為、いつもどうしようもない質問すみません。

1. ItemForm フォームクラス

package jp.co.sss.shop.form; import javax.validation.constraints.Digits; import javax.validation.constraints.Size; import org.hibernate.validator.constraints.NotEmpty; import org.springframework.web.multipart.MultipartFile; public class ItemForm { private String id; @NotEmpty @Size(min = 1, max = 100) private String name; @NotEmpty @Digits(integer = 7, fraction = 0) private String price; @NotEmpty @Size(min = 1, max = 400) private String description; @NotEmpty @Digits(integer = 4, fraction = 0) private String stock; private MultipartFile imageFile; private String image; private String categoryId; private String categoryName; private Integer count; public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; }

2.ItemUpdateAdminControllerコントローラー

package jp.co.sss.shop.controller.item; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; 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.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.multipart.MultipartFile; import jp.co.sss.shop.bean.ItemBean; import jp.co.sss.shop.entity.Category; import jp.co.sss.shop.entity.Item; import jp.co.sss.shop.form.ItemForm; import jp.co.sss.shop.repository.CategoryRepository; import jp.co.sss.shop.repository.ItemRepository; import jp.co.sss.shop.util.BeanCopy; import jp.co.sss.shop.util.Constant; @Controller public class ItemUpdateAdminController { @Autowired ItemRepository itemRepository; @Autowired CategoryRepository categoryRepository; @RequestMapping(path = "/item/update/input", method = RequestMethod.POST) public String updateInput(@ModelAttribute Integer id, Model model) { Item item = itemRepository.findOne(id); ItemBean itemBean = BeanCopy.copyEntityToBean(item); model.addAttribute("item", itemBean); return "item/update/item_update_input"; } @RequestMapping(path = "/item/update/check", method = RequestMethod.POST) public String updateCheck(@Valid @ModelAttribute ItemForm form,BindingResult result,Model model) { if(result.hasErrors()){ return back(model,form); } if (form.getImageFile().getSize() > 0) { MultipartFile file = form.getImageFile(); // アップロード対象のファイル名を取得 String imageName = file.getOriginalFilename(); // 現在の日時を「yyyyMMddhhmmss」形式の文字列として取得 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmmss"); String date = dateFormat.format(new Date()); // ファイルのアップロード先を指定 imageName = date + "_" + imageName; File uploadPath = new File(Constant.FILE_UPLOAD_PATH, imageName); try { // 指定されたファイルを一時的にアップロード file.transferTo(uploadPath); } catch (Exception e) { e.printStackTrace(); return "error"; } // 一時的にアップロードしたファイルの名前をFormクラスにセット form.setImage(imageName); } else { // 商品画像が未入力の場合、登録済みの画像ファイルを取得する Item item = itemRepository.findOne(Integer.parseInt(form.getId())); form.setImage(item.getImage()); } // 選択したカテゴリの名前をFormクラスにセット Category category = categoryRepository.findOne(Integer.parseInt(form.getCategoryId())); form.setCategoryName(category.getName()); return "item/update/item_update_check"; } @RequestMapping(path = "/item/update/complete", method = RequestMethod.POST) public String updateComplete(@ModelAttribute ItemForm form) { // Formクラス内の各フィールドの値をエンティティにコピー Item item = BeanCopy.copyFormToEntity(form); item.setDeleteFlag(Constant.NOT_DELETED); itemRepository.save(item); return "item/update/item_update_complete"; } @RequestMapping(path = "/item/update/input/back", method = RequestMethod.POST) public String back(Model model, @ModelAttribute ItemForm form) { // ItemFormクラスの各フィールドの値をItemBeanクラスにコピー ItemBean itemBean = BeanCopy.copyFormToBean(form); model.addAttribute("item", itemBean); return "item/update/item_update_input"; } }

3.item_update_check.html

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="common/layout_4block"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> </head> <body> <th:block layout:fragment="layout-main"> <div class="title">商品更新入力画面</div> <div class="container"> <p>更新する商品を入力してください。</p> <form th:action="@{/item/update/check}" enctype="multipart/form-data" method="post" th:object="${ItemForm}"> <div class="text">商品名</div> <div> <input type="text" name="name" th:value="${item.name}" /> <span th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></span> </div> <div class="text">価格</div> <div> <input type="text" name="price" th:value="${item.price}" /> <span th:if="${#fields.hasErrors('price')}" th:errors="*{price}"></span> </div> <div class="text">説明文</div> <div> <textarea name="description" rows="6" th:field="${item.description}"></textarea> <span th:if="${#fields.hasErrors('description')}" th:errors="*{description}"></span> </div> <div class="text">カテゴリ</div> <div> <select name="categoryId"> <option th:each="category: ${session.categories}" th:value="${category.id}" th:selected="${category.id == item.categoryId}" th:text="${category.name}"></option> </select> </div> <div class="text">在庫数</div> <div> <input type="text" name="stock" th:value="${item.stock}" /> <span th:if="${#fields.hasErrors('stock')}" th:errors="*{stock}"></span> </div> <div class="text">商品画像</div> <div> <div class="value"> <span th:if="${item.image != null}"> <img th:src="@{/img/{image}(image=${item.image})}"></img> </span> <span th:if="${item.image == null}"> <img th:src="@{/img/common/no_image.png}"></img> </span> </div> <div> <input type="file" name="imageFile" /> </div> </div> <input type="hidden" name="id" th:value="${item.id}" /> <input type="submit" value="送信" /> </form> <form th:action="@{/item/list/admin}"> <input type="submit" value="戻る" /> </form> </div> </th:block> </body> </html>

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

A-pZ

2018/03/18 11:19

return "item/update/item_update_input"; で示されてるhtmlがないようですが、 item_update_checkと同じでしょうか?
kiichan

2018/03/18 12:48

大変失礼致しました。はい上記でcheakと書いてしまいました。cheakではなくinputです。
guest

回答2

0

(1) th:object="${ItemForm}" による java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'ItemForm' available as request attribute の問題について:

ItemFormクラスの内容を参照する場合は、単純に ${itemForm} で良いです。このとき、Controllerの引数に

java

1@ModelAttribute ItemForm form

が必要です。

(2) Exception evaluating SpringEL expression: "#fields.hasErrors('name')" の問題について:

(1)の問題が発生すると立て続けにThymeleaf側で解析できないため出る問題です。(1)が解決できれば自動的に解決されます。

投稿2018/03/19 10:10

A-pZ

総合スコア12011

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kiichan

2018/03/19 14:04

回答いつもありがとうございます。 とても助かりました。 上記の内容を試すと画面遷移まではいきました。 ただ、未入力にすると java.lang.IllegalArgumentException: null とエラーが消えません。 コントローラーの return back(model,form); ItemBean itemBean = BeanCopy.copyFormToBean(form);が おかしいとコンソールにて出てしまいます。 このような質問すみません。
kiichan

2018/03/19 14:20

ブラウザ上ではソースからターゲットにプロパティ 'count'をコピーできませんでした。ネストされた例外はjava.lang.IllegalArgumentException と表示されます。 countはformクラスでしか定義していないのです。
A-pZ

2018/03/20 00:52

ItemBean itemBean = BeanCopy.copyFormToBean(form); 入力フォームの内容をItemBeanにコピーするのは果たして正しいのでしょうか、という疑問がわきました。 return back(model,form)を呼び出さず、 if (result.hasErrors()) { model.addAttribute("item", form); } でも良いかと思います。
guest

0

itemFormがnullまたは未定義なのでは?

投稿2018/03/18 12:42

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kiichan

2018/03/18 12:52

上記の th:object="${ItemForm}"がnullか未定義ということでしょうか。。
退会済みユーザー

退会済みユーザー

2018/03/18 12:56

ですね。 updateInput を基点とすると発生しそうにみえますから
kiichan

2018/03/19 14:07

まだ解決はしていませんが、わかりやすいヒントをいつもありがとうございます。とても助かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問