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

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

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

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

Spring Boot

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

Q&A

解決済

1回答

7074閲覧

SpringBoot Thymeleaf フォームから送信しDBに格納した値の改行コードがtextに反映されない

chocolate_pie

総合スコア26

Thymeleaf

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

Spring Boot

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

0グッド

0クリップ

投稿2020/01/12 15:48

編集2020/01/13 03:40

前提・実現したいこと

textareaから入力された改行を含む文字列をDBに改行コード入りで格納して、
改行された状態で別ページでth:textとして表示したいです。

入力フォームから改行されて登録された値をCSV出力したところ、改行コード\nが入っていました。
が、DBViwerで中身を見ると何も改行コードがありません。
また、入力フォームのtextareaで既存データを表示する際は改行されて表示されます。
利用しているDBはMySQlです。

表示したいページではThymeleafで改行を記述する方法Thymeleafで文字列の改行コードを<br />に変換して出力するを試したらエラーが起きてしまいました。
何もせずth:textとして表示するとなぜか改行でなくスペースで表示されます。

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

エラーメッセージ(表示したいページ) Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method split(java.lang.String,java.lang.Integer) cannot be found on type jp.co.itc.mbo.entity.CoGoal Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "cogoal.split('\r\n|\r|\n', -1)" (template: "goals/goal_list" - line 32, col 17)

該当のソースコード

cogoal.html(入力ページ)

HTML

1<!DOCTYPE html> 2<html xmlns:th="http://www.thymeleaf.org"> 3<head> 4<meta charset="UTF-8"> 5<title>会社目標編集</title> 6</head> 7<body> 8 <h1>会社目標編集</h1> 9 10 <form method="post" th:action="@{/cogoal/complete}"> 11 <table> 12 <tr> 13 <th>年度</th> 14 <th>会社目標</th> 15 </tr> 16 17 <tr th:object="${cogoal}"> 18 <td> 19 <p th:text="*{year}"></p> <input type="hidden" name="year" 20 th:value="*{year}"> 21 </td> 22 <td><textarea name="cogoal" th:field="*{cogoal}" cols="40" 23 rows="8" required wrap="hard"></textarea></td> 24 <tr> 25 </table> 26 27 <br> <input type="submit" value="更新" /> 28 </form> 29 <div class=return> 30 <button onclick="location.href='/admin/menu'">戻る</button> 31 </div> 32</body> 33</html>

Controller(入力ページ)

java

1@RequestMapping("admin/cogoalinput") 2 public String coGoalInput(Model model) { 3 //既存目標の表示 4 CoGoal cogoal = cogoalservice.findCurrent(); 5 if(cogoal==null) { 6 return "admins/cogoal_new"; 7 } 8 model.addAttribute("cogoal", cogoal); 9 10 return "admins/cogoal"; 11 12 } 13@RequestMapping(path = "/cogoal/complete", method = RequestMethod.POST) 14 public String createCoGoal(Principal principal, CoGoalForm cogoalform) { 15 16 //今ログインしている人のID 17 Authentication auth = (Authentication) principal; 18 UserMaster loginuser = (UserMaster) auth.getPrincipal(); 19 //時間取ってくる 20 Timestamp timestamp = new Timestamp(System.currentTimeMillis()); 21 //既存目標のdelete_flgをtrueにする 22 CoGoal cogoalold = cogoalservice.findCurrent(); 23 cogoalold.setDeleteflg(true); 24 cogoalold.setUpdatedat(timestamp); 25 cogoalold.setUpdatedby(loginuser.getId()); 26 cogoalservice.save(cogoalold); 27 //新規目標作成 28 CoGoal cogoal = new CoGoal(); 29 cogoal.setYear(cogoalform.getYear()); 30 cogoal.setCogoal(cogoalform.getCogoal()); 31 cogoal.setCreatedat(timestamp); 32 cogoal.setDeleteflg(false); 33 cogoal.setUpdatedat(timestamp); 34 cogoal.setUpdatedby(loginuser.getId()); 35 cogoalservice.save(cogoal); 36 37 return "redirect:/admin/cogoalinput"; 38 39 }

goal_list.html(表示したいページ)

HTML

1<!DOCTYPE html> 2<html xmlns:th="http://www.thymeleaf.org" th:fragment=""> 3<head> 4<meta charset="UTF-8"> 5<title>目標一覧</title> 6<link th:href="@{/css/style.css}" rel="stylesheet" /> 7<script th:src="@{/js/mboapp.js}" type="text/javascript"></script> 8</head> 9<body> 10 <h1>会社目標一覧</h1> 11 12 <table> 13 <tr> 14 <th>年度</th> 15 <th>会社目標</th> 16 <th>部目標</th> 17 <th>チーム目標</th> 18 </tr> 19 <tr> 20 <!-- th:object 1行分取ってくる --> 21 <td> 22 <p th:if="${cogoal}" th:text="${cogoal.year}"></p> 23 <p th:if="${cogoal} == null">設定されてません</p> 24 </td> 25 <td> 26 <p> 27 <th:block th:if="${cogoal}"> 28 <!-- ヌルポ対策 --> 29 <th:block th:each="line: ${cogoal.split('\r\n|\r|\n', -1)}"> 30 <!-- 改行コードでsplitしてループ --> 31 <th:block th:text="${line}" /> 32 <br /> 33 </th:block> 34 </th:block> 35 </p> 36 <p th:if="${cogoal} == null">設定されていません</p> 37 </td> 38 39 40 <td><p th:if="${deptgoal}" th:text="${deptgoal.deptgoal}"></p> 41 <p th:if="${deptgoal} == null">設定されていません</p></td> 42 <!-- <td th:text="${deptgoal.deptgoal}"></td>--> 43 <td> 44 <p th:if="${teamgoal}" th:text="${teamgoal.teamgoal}"></p> 45 <p th:if="${teamgoal} == null">設定されていません</p> 46 </td> 47 <!-- <td th:text="${teamgoal.teamgoal}"></td> --> 48 </tr> 49 </table> 50</body> 51</html>

Controller(表示したいページ)

java

1@RequestMapping("/{id}") 2 public String showGoal(@PathVariable Integer id, Model model) { 3 4 //ユーザ情報の取得 5 UserMaster usermaster = usermasterservice.findOne(id); 6 model.addAttribute("userid", usermaster); 7 8 //会社目標を表示するメソッド 9 CoGoal cogoal = cogoalservice.findCurrent(); 10 model.addAttribute("cogoal", cogoal); 11 12 //部目標を表示するメソッド 13 DeptMaster userdeptid = usermaster.getDeptid(); 14 DeptGoal deptgoal = deptgoalservice.findCurrentOne(userdeptid.getId()); 15 model.addAttribute("deptgoal", deptgoal); 16 17 //チーム目標を表示するメソッド 18 TeamMaster userteamid = usermaster.getTeamid(); 19 TeamGoal teamgoal = teamgoalservice.findCurrentOne(userteamid.getId()); 20 model.addAttribute("teamgoal", teamgoal); 21 22 return "goals/goal_list"; 23 } 24

DBの中身CSV(cogoal)
イメージ説明

試したこと

・表示したいページのタイプをpタグでなくtextareaで囲んだ→値が空白になってしまった
・DBに直接改行コードを書き込んだ→文字列としてみなされてしまった

追記
①thymeleafで以下のようなコードを書いて試しましたがスペースで表示されるのは変わりませんでした。
そもそもDBのデータに\nが入っていないので反応なし。そこで、DBに直で\nを打ち込んだらやはりスペースで表示されました。 &nbspの代わりに<br/>を入れたら文字列として認識されました。

HTML

1<td th:text="*{#strings.replace(cogoal, '\n', ' &nbsp')}" ></td>

②java側で文字列の変換を試みましたがObject型とString型の不一致でHTMLに値が渡りませんでした。

java

1 CoGoal cocogoal = cogoalservice.findCurrent(); 2 String cogoal1=cocogoal.toString(); 3 String cogoal=cogoal1.replace("\n", "&nbsp"); 4 model.addAttribute("cogoal", cogoal);

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

何時間調べてもわからず本当に困っています。
初心者で至らないところがあると思いますがよろしくお願いいたします。

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

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

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

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

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

chocolate_pie

2020/01/13 03:05

コメントありがとうございます。 m.ts10806様 コメントありがとうございます。 そもそもDBの値に/nが入っていないことになっていたので処理がされていませんでした。 そこで、DBに直に/nを入力し、ご提示いただきましたURLを参照させていただき、 <td th:text="*{#strings.replace(cogoal, '\n', '&nbsp;')}" ></td> と書いたところ、スペースで表示されました。
m.ts10806

2020/01/13 03:07

改行コードは環境依存となるところなので、直に\nと打つと別の環境で動かなくなる可能性があります。 textareaからの送信なのであればあくまでtextareaから送信された情報を使った方が良いと思います。 あとはreplace()の引数を&nbsp;を<br />として試行錯誤ですかね。
chocolate_pie

2020/01/13 03:20

アドバイスありがとうございます。 <br/>に変えると ①直打ちした方→文字列 ②フォームから受け取った値→反応せず でした。ご教授いただきありがとうございました。
m.ts10806

2020/01/13 03:24

改行コードとして \r\n または \r が入ってるのではないでしょうか。
chocolate_pie

2020/01/13 03:36

これで試しましたが、やはりフォームから受けっとった値の表示は何も変わりませんでした。 <td th:text="*{#strings.replace(cogoal, '\r\n|\r|\n', '<br/>')}" ></td> やはり登録の際、改行コードが正確にDBに格納されていないことが原因だと思われます。
guest

回答1

0

自己解決

難しく考えすぎましたが、*を$と間違えるという非常に単純なミスをしていました…。
この質問の中で様々な方法で検証できたので勉強になりました。

Before

HTML

1<p> 2 <th:block th:if="${cogoal}"> 3 <!-- ヌルポ対策 --> 4 <th:block th:each="line: ${cogoal.split('\r\n|\r|\n', -1)}"> 5 <!-- 改行コードでsplitしてループ --> 6 <th:block th:text="${line}" /> 7 <br /> 8 </th:block> 9 </th:block> 10 </p>

After

HTML

1 <p> 2 <th:block th:if="*{cogoal}"> 3 <!-- ヌルポ対策 --> 4 <th:block th:each="line: *{cogoal.split('\r\n|\r|\n', -1)}"> 5 <!-- 改行コードでsplitしてループ --> 6 <th:block th:text="${line}" /> 7 <br /> 8 </th:block> 9 </th:block> 10 </p> 11

これで改行されました。お騒がせしました。

投稿2020/01/13 04:05

chocolate_pie

総合スコア26

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問