spring boot: 用thymeleaf嵌套循环展示多层数据(spring boot 2.3.2)
一,什么情况下会用到嵌套循环?
当我们展示多个分类时,每个分类下又展示出推荐的前几个商品,
这时我们需要用到嵌套循环
看一个例子:

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest
对应的源码可以访问这里获取: https://github.com/liuhongdi/
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,演示项目的相关信息
1,项目地址:
https://github.com/liuhongdi/templateloop
2,项目功能说明:
演示了模板中常用的嵌套循环
3,项目结构;如图:

三,配置文件说明
1,pom.xml
<!--thymeleaf begin-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--thymeleaf end-->
2,application.properties
#error
server.error.include-stacktrace=always
#error
logging.level.org.springframework.web=trace #thymeleaf
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode=HTML
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
四,java程序说明
1,Category.java
//分类模型
public class Category { //分类id
Long categoryId;
public Long getCategoryId() {
return this.categoryId;
}
public void setCategoryId(Long categoryId) {
this.categoryId = categoryId;
} //分类名称
private String categoryName;
public String getCategoryName() {
return this.categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
} //打印
public String toString(){
return " Category:categoryId=" + categoryId +" categoryName=" + categoryName;
}
}
2,Goods.java
//商品模型
public class Goods {
//商品id
Long goodsId;
public Long getGoodsId() {
return this.goodsId;
}
public void setGoodsId(Long goodsId) {
this.goodsId = goodsId;
} //商品名称
private String goodsName;
public String getGoodsName() {
return this.goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
} //商品标题
private String subject;
public String getSubject() {
return this.subject;
}
public void setSubject(String subject) {
this.subject = subject;
} //商品价格
private BigDecimal price;
public BigDecimal getPrice() {
return this.price;
}
public void setPrice(BigDecimal price) {
this.price = price;
} //库存
int stock;
public int getStock() {
return this.stock;
}
public void setStock(int stock) {
this.stock = stock;
} //打印
public String toString(){
return " Goods:goodsId=" + goodsId +" goodsName=" + goodsName+" subject=" + subject+" price=" + price+" stock=" + stock;
}
}
3,HomeController.java
@Controller
@RequestMapping("/home")
public class HomeController { //返回分栏目的商品列表
@GetMapping("/category")
public String home(Model model) {
//统一使用一个list返回
ArrayList<Map<String,Object>> list = new ArrayList<>(); //每个分类及分类下的推荐商品,用一个map来保存
//第一个分类
Map<String,Object> map1 = new HashMap<String,Object>();
Category category1 = new Category(); category1.setCategoryId(1L);
category1.setCategoryName("家居");
map1.put("category",category1); //保存商品用的list
ArrayList<Goods> listGoods1 = new ArrayList<Goods>(); Goods goods1 = new Goods();
goods1.setGoodsId(1L);
goods1.setGoodsName("无线智能感应灯");
listGoods1.add(goods1);
Goods goods2 = new Goods();
goods2.setGoodsId(2L);
goods2.setGoodsName("朱之光落地灯");
listGoods1.add(goods2);
Goods goods3 = new Goods();
goods3.setGoodsId(3L);
goods3.setGoodsName("儿童抗首菌枕头");
listGoods1.add(goods3);
Goods goods4 = new Goods();
goods4.setGoodsId(4L);
goods4.setGoodsName("按摩床垫升级款");
listGoods1.add(goods4);
Goods goods5 = new Goods();
goods5.setGoodsId(5L);
goods5.setGoodsName("北欧简约金属茶几");
listGoods1.add(goods5);
map1.put("goodslist",listGoods1); //把map1添加到list
list.add(map1); //第二个分类
Map<String,Object> map2 = new HashMap<String,Object>();
Category category2 = new Category();
category2.setCategoryId(2L);
category2.setCategoryName("美护");
map2.put("category",category2);
ArrayList<Goods> listGoods2 = new ArrayList<Goods>(); Goods goods21 = new Goods();
goods21.setGoodsId(21L);
goods21.setGoodsName("护手霜套装");
listGoods2.add(goods21);
Goods goods22 = new Goods();
goods22.setGoodsId(22L);
goods22.setGoodsName("美白牙贴");
listGoods2.add(goods22);
Goods goods23 = new Goods();
goods23.setGoodsId(23L);
goods23.setGoodsName("口腔护理泡沫");
listGoods2.add(goods23);
map2.put("goodslist",listGoods2);
//把map2添加到list
list.add(map2); //第三个分类
Map<String,Object> map3 = new HashMap<String,Object>();
Category category3 = new Category();
category3.setCategoryId(3L);
category3.setCategoryName("服装");
map3.put("category",category3);
ArrayList<Goods> listGoods3 = new ArrayList<Goods>(); Goods goods31 = new Goods();
goods31.setGoodsId(31L);
goods31.setGoodsName("纯色真丝睡袍");
listGoods3.add(goods31);
Goods goods32 = new Goods();
goods32.setGoodsId(32L);
goods32.setGoodsName("蚕丝条纹睡衣套装");
listGoods3.add(goods32);
Goods goods33 = new Goods();
goods33.setGoodsId(33L);
goods33.setGoodsName("牛津长袖衬衫");
listGoods3.add(goods33);
map3.put("goodslist",listGoods3);
////把map3添加到list
list.add(map3); //把list传递给模板
model.addAttribute("list",list);
return "home/category.html";
}
}
说明:我们没有使用数据库,因为只是用于演示,
直接用代码写入了11条数据,共三个分类
每个分类的数据各放入一个map中,最后用一个list传递给模板
4,category.html
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div style="width:100%;height:30px;background:#ffffff;font-size: 16px;" ></div>
<div id="content" style="width:1040px;">
<div style="width:790px;float:left;margin-left:30px;">
<!--main begin-->
<div th:each="categoryOne:${list}" style="width:790px;font-size:16px;overflow: hidden;">
<!--显示分类信息-->
<div style="background:#eeeeee;width:790px;height:20px;line-height:20px;overflow: hidden;margin-top: 10px;">
<div style="width:200px;float:left;">
分类ID:<span th:text="${categoryOne.category.categoryId}"></span> 分类名称:<span th:text="${categoryOne.category.categoryName}"></span>
</div> <div style="width:200px;float:right;text-align: right;">
<a th:href="@{/goods/goodslist/(categoryid=${categoryOne.category.categoryId})}">更多...</a>
</div>
</div>
<!--显示分类下的商品列表信息-->
<div style="width:790px;height:100px;">
<div th:each="goodsOne:${categoryOne.goodslist}" style="width:250px;height:100px;float: left;background:#eeeeee;margin-left:10px;margin-top:10px;">
<div>商品ID:[[${goodsOne.goodsId}]]</div>
<div>商品名称:[[${goodsOne.goodsName}]]</div>
</div>
</div>
</div>
<!--main end-->
</div>
</div>
</body>
</html>
注意代码中用了th:each嵌套循环了两层,变量名分别用了categoryOne和goodsOne
五,测试效果
访问:
http://127.0.0.1:8080/home/category
返回:

循环展示了多个分类下的多个商品
六,查看spring boot版本
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.2.RELEASE)
spring boot: 用thymeleaf嵌套循环展示多层数据(spring boot 2.3.2)的更多相关文章
- 77. Spring Boot Use Thymeleaf 3【从零开始学Spring Boot】
[原创文章,转载请注明出处] Spring Boot默认选择的Thymeleaf是2.0版本的,那么如果我们就想要使用3.0版本或者说指定版本呢,那么怎么操作呢?在这里要说明下 3.0的配置在spri ...
- spring boot整合Thymeleaf的那些坑(spring boot 学习笔记之四)
这里简单记录一下Thymeleaf配置和使用的步骤 1.修改pom文件,添加依赖 <dependency> <groupId>org.springframework.boot& ...
- Spring Boot☞ 使用Thymeleaf模板引擎渲染web视图
静态资源访问 在我们开发Web应用的时候,需要引用大量的js.css.图片等静态资源. 默认配置 Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则: /s ...
- Spring Boot2(五):使用Spring Boot结合Thymeleaf模板引擎使用总结
一.Thymeleaf概述 一般来说,常用的模板引擎有JSP.Velocity.Freemarker.Thymeleaf . SpringBoot推荐的 Thymeleaf – 语法更简单,功能更强大 ...
- Spring Boot2 系列教程(九)Spring Boot 整合 Thymeleaf
虽然现在慢慢在流行前后端分离开发,但是据松哥所了解到的,还是有一些公司在做前后端不分的开发,而在前后端不分的开发中,我们就会需要后端页面模板(实际上,即使前后端分离,也会在一些场景下需要使用页面模板, ...
- Spring Boot 2.X(三):使用 Spring MVC + MyBatis + Thymeleaf 开发 web 应用
前言 Spring MVC 是构建在 Servlet API 上的原生框架,并从一开始就包含在 Spring 框架中.本文主要通过简述 Spring MVC 的架构及分析,并用 Spring Boot ...
- 极简 Spring Boot 整合 Thymeleaf 页面模板
虽然现在慢慢在流行前后端分离开发,但是据松哥所了解到的,还是有一些公司在做前后端不分的开发,而在前后端不分的开发中,我们就会需要后端页面模板(实际上,即使前后端分离,也会在一些场景下需要使用页面模板, ...
- Spring Boot整合Thymeleaf视图层
目录 Spring Boot整合Thymeleaf Spring Boot整合Thymeleaf 的项目步骤 Thymeleaf 语法详解 Spring Boot整合Thymeleaf Spring ...
- Spring Boot和Thymeleaf整合,结合JPA实现分页效果
在项目里,我需要做一个Spring Boot结合Thymeleaf前端模版,结合JPA实现分页的演示效果.做的时候发现有些问题,也查了现有网上的不少文档,发现能全栈实现的不多,所以这里我就把我的做法, ...
随机推荐
- [极客大挑战 2019]Secret File wp
通过标题考虑可能为文件包含漏洞方面 打开网页 从页面并没任何思路,查看源代码 得到有一个跳转到./Archive_room.php的超链接,打开Archive_room.php 中央有一个secret ...
- [LeetCode]96. 不同的二叉搜索树(DP,卡特兰数)
题目 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ ...
- java键对值SHA256加密接口请求
import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.htt ...
- 使用App Metrics实现性能监控
App Metrics监控需要安装InfluxDB时序数据库和Grafana可视化分析工具 1.安装InfluxDB 下载地址:https://portal.influxdata.com/downlo ...
- Linux实战(4):Centos7升级python
记一笔升级python后产生的问题,并给予解决方案.莫慌看下文: 升级python3 我是直接 yum安装的,当然安装方法有很多,不喜欢此安装方式的可选用其他方式,我再此就不一一解释了.安装方式可不同 ...
- 关于orm的个人测试——SqlSugar与FreeSql
前言 转眼已经过了金九,光阴真的是似箭啊,周六日常加班,忙里抽闲就想鼓捣个啥看看,刚好最近想着有没有必要换个orm,从当时原生到Dapper,又到现在的Sqlsugar,因为经常听到几个不错的orm, ...
- netty全局分析1
这个系列都是别人的分析文 https://www.jianshu.com/p/ac7fb5c2640f 一丶 Netty基础入门 Netty是一个高性能.异步事件驱动的NIO框架,它提供了对TCP.U ...
- spring mvc(1) 为什么要使用mvc
在使用spring mvc之前,我们首先要理解我们为什么要使用spring mvc.关于这个问题我们可以看一下java web的简单发展过程. 1. servlet 开发阶段 上世纪90年代,随着In ...
- 1000000 / 60S 的 RocketMQ 不停机,扩容,平滑升级!
一.背景 1.各业务系统持续迭代过程中,JDK.SpringBoot.RocketMQ Client 等框架也进行了升级,高版本的 RocketMQ Client 发送的消息到低版本中,在控制台中午无 ...
- Python3 环境搭建 保姆式 详细教程!真手把手教学!
本文我们将向大家介绍如何在本地搭建 Python3 开发环境. Python3 可应用于多平台包括 Windows.Linux 和 Mac OS X. Unix (Solaris, Linux, Fr ...