一灰灰blog 一灰灰blog
首页
  • InfluxDB
  • MongoDB
  • MySql
  • 基础系列
  • DB系列
  • 搜索系列
  • MQ系列
  • WEB系列
  • 中间件
  • 运维
  • SpringSecurity
  • SpringCloud
  • QuickAlarm
  • QuickCrawer
  • QuickFix
  • QuickMedia
  • QuickSpi
  • QuickTask
  • 高可用
  • 分类
  • 标签
  • 归档
  • 收藏
  • 关于
GitHub (opens new window)

一灰灰blog

资深搬运工
首页
  • InfluxDB
  • MongoDB
  • MySql
  • 基础系列
  • DB系列
  • 搜索系列
  • MQ系列
  • WEB系列
  • 中间件
  • 运维
  • SpringSecurity
  • SpringCloud
  • QuickAlarm
  • QuickCrawer
  • QuickFix
  • QuickMedia
  • QuickSpi
  • QuickTask
  • 高可用
  • 分类
  • 标签
  • 归档
  • 收藏
  • 关于
GitHub (opens new window)
  • 基础系列

  • DB系列

  • 搜索系列

  • MQ系列

  • WEB系列

    • Request

    • Response

      • 【WEB系列】Freemaker环境搭建
      • 【WEB系列】Thymeleaf环境搭建
      • 【WEB系列】Beetl环境搭建
      • 【WEB系列】返回文本、网页、图片的操作姿势
      • 【WEB系列】请求重定向
      • 【WEB系列】404、500异常页面配置
      • 【WEB系列】全局异常处理
      • 【WEB系列】自定义异常处理HandlerExceptionResolver
      • 【WEB系列】开启GZIP数据压缩
      • 【WEB系列】RestTemplate 4xx/5xx 异常信息捕获
      • 【WEB系列】自定义返回Http Code的n种姿势
      • 【WEB系列】异步请求知识点与使用姿势小结
      • 【WEB系列】SSE服务器发送事件详解
      • 【WEB系列】thymeleaf foreach踩坑记录
        • I. 项目搭建
          • 1. 项目依赖
        • II. 问题复现与处理
          • 1. 场景复现
          • 2. 原因说明
        • III. 不能错过的源码和相关知识点
          • 0. 项目
          • 1. 微信公众号: 一灰灰Blog
      • 【WEB系列】如何支持下划线驼峰互转的传参与返回
    • RestTemplate

    • WebClient

    • WebFlux

    • WebSocket

    • Web三剑客

    • 实例

    • 其他

  • 中间件

  • 运维

  • SpringSecurity

  • SpringCloud

  • Spring系列
  • WEB系列
  • Response
一灰灰
2021-11-13

【WEB系列】thymeleaf foreach踩坑记录

话说自从前后端分离之后,前后端放在一起的场景就很少了,最近写个简单的后台,突然踩坑了,使用themeleaf模板渲染时,发现th:each来遍历生成表单数据,一直抛异常,提示Property or field 'xxx' cannot be found on null

接下来看一下这个问题到底是个什么情况

# I. 项目搭建

# 1. 项目依赖

本项目借助SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA进行开发

开一个web服务用于测试

<dependencies>
    <!-- 邮件发送的核心依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
</dependencies>
1
2
3
4
5
6
7
8
9
10
11

配置文件application.yml

server:
  port: 8080

spring:
  thymeleaf:
    mode: HTML
    encoding: UTF-8
    servlet:
      content-type: text/html
    cache: false
1
2
3
4
5
6
7
8
9
10

# II. 问题复现与处理

# 1. 场景复现

一个最基础的demo,来演示一下问题

@Controller
public class IndexController {
  public Map<String, Object> newMap(String key, Object val, Object... kv) {
      Map<String, Object> map = new HashMap<>();
      map.put(key, val);
      for (int i = 0; i < kv.length; i += 2) {
          map.put(String.valueOf(kv[i]), kv[i + 1]);
      }
      return map;
  }

  @GetMapping(path = "list")
  public String list(Model model) {
      List<Map> list = new ArrayList<>();
      list.add(newMap("user", "yh", "name", "一灰"));
      list.add(newMap("user", "2h", "name", "2灰"));
      list.add(newMap("user", "3h", "name", "3灰"));
      model.addAttribute("list", list);
      return "list";
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

对应的html文件如下(注意,放在资源目录 templates 下)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
</head>
<body>

<div>
    <div th:each="item: ${list}">
        <span th:text="${item.user}"></span>
        &nbsp;&nbsp;
        <span th:text="${item.name}"></span>
    </div>

    <hr/>

    <p th:each="item: ${list}">
        <p th:text="${item.user}"></p>
        &nbsp;&nbsp;
        <p th:text="${item.name}"></p>
    </p>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

注意上面的模板,有两个each遍历,出现问题的是第二个

# 2. 原因说明

上面提示user没有,那么是否是语法问题呢?将html改成下面这个时

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
</head>
<body>

<div>
    <div th:each="item: ${list}">
        <span th:text="${item.user}"></span>
        &nbsp;&nbsp;
        <span th:text="${item.name}"></span>
    </div>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

相同的写法,上面这个就可以,经过多方尝试,发现出现问题的原因居然是<p>这个标签

简单来讲,就是<p>标签不能使用th:each,测试一下其他的标签之后发现<img>,<input>标签也不能用

那么问题来了,为啥这几个标签不能使用each呢?

这个原因可能就需要去瞅一下实现逻辑了,有知道的小伙伴可以科普一下

# III. 不能错过的源码和相关知识点

# 0. 项目

  • 工程:https://github.com/liuyueyi/spring-boot-demo (opens new window)
  • 源码:https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/ (opens new window)

# 1. 微信公众号: 一灰灰Blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

  • 一灰灰Blog个人博客 https://blog.hhui.top (opens new window)
  • 一灰灰Blog-Spring专题博客 http://spring.hhui.top (opens new window)

一灰灰blog

编辑 (opens new window)
#Thymeleaf
上次更新: 2022/02/27, 11:13:23
【WEB系列】SSE服务器发送事件详解
【WEB系列】如何支持下划线驼峰互转的传参与返回

← 【WEB系列】SSE服务器发送事件详解 【WEB系列】如何支持下划线驼峰互转的传参与返回→

最近更新
01
【基础系列】基于maven多环境配置
04-25
02
【WEB系列】内嵌Tomcat配置Accesslog日志文件生成位置源码探索
04-24
03
【搜索系列】ES查询常用实例演示
04-18
更多文章>
Theme by Vdoing | Copyright © 2017-2022 一灰灰Blog
MIT License | 鄂ICP备18017282号 |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×