Thymeleaf 搭建家居网首页

news2025/1/11 23:39:35

文章目录

    • 1.引入Thymeleaf sunliving-commodity模块
        • 1.在resources目录下引入Thymeleaf 所需资源
        • 2.pom.xml引入Thymeleaf依赖
        • 3.application.yml 关闭缓存,使页面实时刷新
        • 4.在application-prod.yml开启缓存
        • 5.编写com/sun/sunliving/commodity/web/IndexController.java响应templates/index.html
        • 6.index.html和list.html引入thymeleaf的命名空间
        • 7.效果展示
    • 2.首页显示分类
        • 1.显示一级分类
          • 1.后端 sunliving-commodity模块
            • 1.CategoryService.java 获取一级分类
            • 2.CategoryServiceImpl.java
            • 3.IndexController.java 首先测试是否得到一级分类
            • 4.完整 IndexController.java
          • 2.index.html 展示一级菜单
          • 3.结果演示
        • 2.流式计算将集合转为Map
          • 1.实例代码
          • 2.结果
          • 3.解析
        • 3.显示二级和三级分类
          • 1.前端要求的数据格式
          • 2.vo设计Catalog2Vo.java
          • 3.CategoryService.java 根据父id获取节点
          • 4.CategoryServiceImpl.java 实现方法
          • 5.CategoryService.java 获取二级和三级分类,按照前端需要的格式返回
          • 6.CategoryServiceImpl.java 实现方法
          • 7.分析前端请求 static/index/js/catalogLoader.js
            • 1.前端发送请求的代码片段
            • 2.解析
            • 3.为了部署,将这个请求进行多环境的区分,使用环境变量 + 资源路径的方式,上线的时候要手动修改env的值,必须走网关,否则会跨域
          • 8.编写后端的接口
          • 9.测试
            • 1.可以获取数据,但是没有正确展示
            • 2.在index.html加一句话
            • 3.重启访问,成功显示!

1.引入Thymeleaf sunliving-commodity模块

1.在resources目录下引入Thymeleaf 所需资源

image-20240425172628917

2.pom.xml引入Thymeleaf依赖
        <!-- 引入thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
3.application.yml 关闭缓存,使页面实时刷新

image-20240425174410743

4.在application-prod.yml开启缓存

image-20240425174432594

5.编写com/sun/sunliving/commodity/web/IndexController.java响应templates/index.html
package com.sun.sunliving.commodity.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/4/25 17:50
 * @Version 1.0
 */
@Controller
public class IndexController {
    // 响应templates/index.html
    // 当请求路径为http://localhost:8080/ 或 http://localhost:8080/index时,返回index.html页面
    @GetMapping({"/", "/index.html"})
    public String index() {
        return "index";
    }

}

6.index.html和list.html引入thymeleaf的命名空间

image-20240425180109440

<html lang="en" xmlns:th="http://www.thymeleaf.org">
7.效果展示

image-20240425195100771

2.首页显示分类

1.显示一级分类
1.后端 sunliving-commodity模块
1.CategoryService.java 获取一级分类
    /**
     * 获取一级分类
     * @return
     */
    List<CategoryEntity> getLevel1Category();
2.CategoryServiceImpl.java
    @Override
    public List<CategoryEntity> getLevel1Category() {
        // 查询一级分类
        List<CategoryEntity> categoryEntities = categoryDao.selectList(new QueryWrapper<CategoryEntity>().eq("parent_id", 0));
        return categoryEntities;
    }
3.IndexController.java 首先测试是否得到一级分类

image-20240426085808273

4.完整 IndexController.java
@Controller
public class IndexController {
    @Resource
    private CategoryService categoryService;
    // 响应templates/index.html
    // 当请求路径为http://localhost:8080/ 或 http://localhost:8080/index时,返回index.html页面
    @GetMapping({"/", "/index.html"})
    public String index(Model model) {
        // 获取一级分类
        List<CategoryEntity> categoryEntities = categoryService.getLevel1Category();
        // 将一级分类放到model中
        model.addAttribute("categotries", categoryEntities);
        return "index";
    }

}

2.index.html 展示一级菜单

image-20240426091110112

3.结果演示

image-20240426091134830

2.流式计算将集合转为Map
1.实例代码
import lombok.Data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/4/26 9:59
 * @Version 1.0
 */
public class Test {
    public static void main(String[] args) {
        List<Stu> stus = new ArrayList<>();
        // 添加元素
        stus.add(new Stu(1, "张三", "北京", "篮球"));
        stus.add(new Stu(2, "李四", "上海", "足球"));
        stus.add(new Stu(3, "王五", "广州", "乒乓球"));
        // 将List转为Map,key为name,value为Stu2对象的列表
        Map<String, ArrayList<Stu2>> collect = stus.stream().collect(Collectors.toMap(k -> {
            // 这个k代表每一个Stu对象
            return k.getName();
        }, v -> {
            // 这个v代表Stu2对象的列表
            Stu2 stu2 = new Stu2();
            stu2.setHobby(v.getHobby());
            stu2.setName(v.getName());
            Stu2 stu21 = new Stu2();
            stu21.setHobby(v.getHobby());
            stu21.setName(v.getName() + "克隆");
            ArrayList<Stu2> stu2s = new ArrayList<>();
            stu2s.addAll(Arrays.asList(stu2, stu21));
            return stu2s;
        }));
        // 输出collect
        System.out.println(collect);
    }
}

@Data
class Stu {
    private Integer id;
    private String name;
    private String address;
    private String hobby;
    // 全参构造
    public Stu(Integer id, String name, String address, String hobby) {
        this.id = id;
        this.name = name;
        this.address = address;
        this.hobby = hobby;
    }
}

@Data
class Stu2 {
    private String name;
    private String hobby;
}
2.结果

image-20240426101928297

3.解析
  • 流式计算就是对每一个遍历的List对象进行操作,在这里就是将其转化为Map
  • 其中的k,v指的都是List中的每一个对象
  • 用语言描述就是,将List化为流,收集每一个元素作为Map
3.显示二级和三级分类
1.前端要求的数据格式

image-20240426092244393

2.vo设计Catalog2Vo.java
package com.sun.sunliving.commodity.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/4/26 9:33
 * @Version 1.0
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Catalog2Vo {
    // 一级分类id
    private String catalog1Id;
    // 三级分类信息的集合
    List<Category3Vo> catalog3List;
    // 二级分类的id和名称
    private String id;
    private String name;
    // 三级分类信息
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Category3Vo {
        // 二级分类id
        private String catalog2Id;
        // 三级分类id
        private String id;
        // 三级分类名称
        private String name;
    }
}

3.CategoryService.java 根据父id获取节点
    /**
     * 根据父id获取所有节点
     *
     * @param selectList
     * @param parentCId
     * @return
     */
    List<CategoryEntity> getParent_cid(List<CategoryEntity> selectList, Long parentCId);
4.CategoryServiceImpl.java 实现方法
    @Override
    public List<CategoryEntity> getParent_cid(List<CategoryEntity> selectList, Long parentCId) {
        List<CategoryEntity> collect = selectList.stream().filter(
                item -> {
                    return item.getParentId().equals(parentCId);
                }
        ).collect(Collectors.toList());
        return collect;
    }
5.CategoryService.java 获取二级和三级分类,按照前端需要的格式返回
    /**
     * 获取二级和三级分类,按照前端需要的格式返回
     * @return
     */
    Map<String, List<Catalog2Vo>> getCatalogJson();
6.CategoryServiceImpl.java 实现方法
    @Override
    public Map<String, List<Catalog2Vo>> getCatalogJson() {
        // 首先查询所有分类
        List<CategoryEntity> categoryEntities = categoryDao.selectList(null);
        // 然后使用辅助方法获取一级分类
        List<CategoryEntity> parentCid = getParent_cid(categoryEntities, 0L);
        // 使用streamapi 将一级分类转换为Map
        Map<String, List<Catalog2Vo>> collect = parentCid.stream().collect(Collectors.toMap(
                // key 为一级分类的id
                item -> {
                    return item.getId().toString();
                },
                // value 为二级分类的集合
                item -> {
                    // 获取所有二级分类
                    List<CategoryEntity> catalog2 = getParent_cid(categoryEntities, item.getId());
                    // 将二级分类转换为 Catalog2Vo
                    List<Catalog2Vo> catalog2Vos = catalog2.stream().map(catalog2Item -> {
                        // 将二级分类转换为 Catalog2Vo
                        Catalog2Vo catalog2Vo = new Catalog2Vo();
                        // 一级分类id
                        catalog2Vo.setCatalog1Id(item.getId().toString());
                        // 二级分类id和名称
                        catalog2Vo.setId(catalog2Item.getId().toString());
                        catalog2Vo.setName(catalog2Item.getName());
                        // 获取三级分类
                        List<CategoryEntity> catalog3 = getParent_cid(categoryEntities, catalog2Item.getId());
                        List<Catalog2Vo.Category3Vo> category3Vos = catalog3.stream().map(catalog3Item -> {
                            // 将三级分类转换为 Catalog2Vo.Category3Vo
                            Catalog2Vo.Category3Vo category3Vo = new Catalog2Vo.Category3Vo();
                            category3Vo.setId(catalog3Item.getId().toString());
                            category3Vo.setName(catalog3Item.getName());
                            category3Vo.setCatalog2Id(catalog3Item.getParentId().toString());
                            return category3Vo;
                        }).collect(Collectors.toList());
                        catalog2Vo.setCatalog3List(category3Vos);
                        return catalog2Vo;
                    }).collect(Collectors.toList());
                    return catalog2Vos;
                }
        ));

        return collect;
    }
7.分析前端请求 static/index/js/catalogLoader.js
1.前端发送请求的代码片段

image-20240426135548224

2.解析
  • 可以看出使用的是相对当前页面的路径
  • 查看当前页面的路径 http://localhost:5050/api/sunliving-commodity/index.html#
  • 这样,这个请求就会向http://localhost:5050/api/sunliving-commodity/index/catalog.json
3.为了部署,将这个请求进行多环境的区分,使用环境变量 + 资源路径的方式,上线的时候要手动修改env的值,必须走网关,否则会跨域

image-20240426143738747

8.编写后端的接口
    // static/index/catalog.json
    @ResponseBody
    @GetMapping("/index/catalog.json")
    public Map<String, List<Catalog2Vo>> getCatalogJson() {
        Map<String, List<Catalog2Vo>> catalogJson = categoryService.getCatalogJson();

        return catalogJson;
    }
9.测试
1.可以获取数据,但是没有正确展示

image-20240426144001747

image-20240426144021495

2.在index.html加一句话

image-20240426144221095

3.重启访问,成功显示!

image-20240426144433714

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1698982.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VLAN高级特性

1.VLAN聚合 &#xff08;1&#xff09;VLAN聚合产生的技术背景 &#xff08;2&#xff09;VLAN聚合概述 &#xff08;3&#xff09;VLAN聚合的原理 多个Sub-VLAN共享一个网关地址&#xff0c;节约了子网网络地址、子网定向广播地址、子网缺省网关地址&#xff0c;且各Sub-VLAN…

基于51单片机的超声波液位测量与控制系统

基于51单片机液位控制器 &#xff08;仿真&#xff0b;程序&#xff0b;原理图PCB&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.使用HC-SR04测量液位&#xff0c;LCD1602显示&#xff1b; 2.当水位高于设定上限的时候&#xff0c;对应声光报警报警&am…

【同构字符串】python

思路&#xff1a; 先记录同一个值出现的次数&#xff0c;再将字典中的值取出&#xff0c;比较2个列表即可 代码&#xff1a; class Solution:def isIsomorphic(self, s: str, t: str) -> bool:dit1dict()dit2dict()for i in range(len(s)):if s[i] not in dit1:dit1[s[i…

SQL Server2019安装步骤教程(图文)_最新教程

一、下载SQL Server2019 1.到微软官网下载SQL Server Developer版本&#xff0c;官网当前的2019版本下载需要注册账号。 不想注册的朋友&#xff0c;可以选择从网盘下载&#xff1a;点击此处直接下载 2.下载之后先解压&#xff0c;解压后执行exe安装程序。打开之后的界面如下…

下载 Hugging Face 中的模型文件

下载 Hugging Face 中的模型文件 1. Hugging Face Hub2. ggerganov/whisper.cpp3. 点击图标下载文件4. Clone this model repository5. Using the Hugging Face Client Library6. Using GitReferences 1. Hugging Face Hub The Hugging Face Hub is a platform with over 350k…

linux 常用命令:find grep ps netstat sudo df du rm

rm 命令 删除 -r 是递归参数&#xff08;recursive&#xff09;&#xff0c;用于删除目录及其内容。如果不加这个参数&#xff0c;rm 命令无法删除非空目录。-f 是强制参数&#xff08;force&#xff09;&#xff0c;用于强制删除文件或目录&#xff0c;不会进行任何确认提示…

【fastapi+mongodb】使用motor操作mongodb

上一篇文章&#xff0c;我们在电脑上安装了mongodb数据库。这篇文章&#xff0c;我们在fastapi后端使用motor操作mongodb 如果你还没看过上一篇文章&#xff0c;链接在这里&#xff1a;【MongoDB】安装与使用 安装 motor motor 是一个用于操作 mongodb 数据库的 python 库&a…

【ai】pycharm安装langchain 相关module

pycharm module install 【Python学习 】一篇文章教你PyCharm如何快速安装module 【python】pycharm如何安装python的模块包版本 2024.1.2 RC2 找到当前的虚拟项目 找到解释器 我现在配置为专门为openai-start 准备的3.10 版本+ 号可以找到模块

C++标准库中string的底层实现方式

对于C中 std::string 的一些基本功能和用法&#xff0c;我们应该都很熟悉。但它底层到底是如何实现的呢? 其实在 std::string 的历史中&#xff0c;出现过几种不同的方式。下面我们来一一揭晓。 我们可以从一个简单的问题来探索&#xff0c;一个 std::string 对象占据的内存空…

JavaSE 学习记录

1. Java 内存 2. this VS super this和super是两个关键字&#xff0c;用于引用当前对象和其父类对象 this 关键字&#xff1a; this 关键字用于引用当前对象&#xff0c;即调用该关键字的方法所属的对象。 主要用途包括&#xff1a; 在类的实例方法中&#xff0c;通过 this …

鸿蒙ArkTS声明式开发:跨平台支持列表【触摸事件】

触摸事件 当手指在组件上按下、滑动、抬起时触发。 说明&#xff1a; 开发前请熟悉鸿蒙开发指导文档&#xff1a; gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独…

Spring从零开始学使用系列(四)之@PostConstruct和@PreDestroy注解的使用

如果各位老爷觉得可以&#xff0c;请点赞收藏评论&#xff0c;谢谢啦&#xff01;&#xff01; 文章中涉及到的图片均由AI生成 公众号在最下方&#xff01;&#xff01;&#xff01; 目录 1. 介绍 1.1 PostConstruct概述 1.2 PreDestroy概述 2. 基本用法 2.1 注册CommonAnn…

Docker进入容器查看内容并从容器里拷贝文件到宿主机

工作中需要从docker正在运行的镜像中复制文件到宿主机&#xff0c;于是便将这个过程记录了下来。 &#xff08;1&#xff09;查看正在运行的容器 通过以下命令&#xff0c;可以查看正在运行的容器&#xff1a; docker ps &#xff08;2&#xff09;进入某个容器执行脚本 我…

Pytest对协程异步函数进行单元测试

安装 安装基础包 pytest&#xff0c;pytest-asyncio pip install pytest pytest-asyncio测试&#xff1a; pytest -s -v ./python-code/do-async/aiohttp_session_pytest.py书写规范 类名必须以 Test 开头方法和函数名必须以test开头 class TestAddFunc(object): # 测试…

【mysql】in和exists的区别,not in、not exists、left join的相互转换

【mysql】in和exists的区别&#xff0c;not in、not exists、left join的相互转换 【一】in介绍【1】in中数据量的限制【2】null值不参与in或not in&#xff0c;也就是说in and not in 并不是全量值&#xff0c;排除了null值【3】in的执行逻辑 【二】exists介绍【1】exists no…

学 Go 具体能干什么?

学习 Go (Golang) 后&#xff0c;你可以从事许多不同的工作和项目&#xff0c;Go 语言以其高性能、并发处理和简洁的语法而闻名&#xff0c;特别适合以下几个领域&#xff1a; 1. 后端开发 Go 在后端开发中非常流行&#xff0c;特别适合构建高性能的 Web 服务和 API。 Web 框…

前端开发-添加公用的ts文件,并在Vue文件中引用

一般我们把页面要用的公用函数写在一个ts文件中 通过调用这个ts文件让我们可以在vue文件中使用函数 Eg&#xff1a;我们现在创建一个formRules.ts文件 然后在我们需要调用该函数体的vue文件中 import { required } from "/utils/formRules";有可能语法一开始会提示…

Shell环境变量深入:自定义系统环境变量

Shell环境变量深入&#xff1a;自定义系统环境变量 目标 能够自定义系统级环境变量 全局配置文件/etc/profile应用场景 当前用户进入Shell环境初始化的时候会加载全局配置文件/etc/profile里面的环境变量, 供给所有Shell程序使用 以后只要是所有Shell程序或命令使用的变量…

推荐丨快速申请免费域名证书

背景&#xff1a; 域名是一个IP地址上的“面具” 。一个域名的目的是便于记忆和沟通的一组服务器的地址(网站&#xff0c;电子邮件&#xff0c;FTP等)。 通俗的说&#xff0c;域名就相当于一个家庭的门牌号码&#xff0c;别人通过这个号码可以很容易的找到你。 域名不仅便于记…

Python轻松玩转excel操作指导

目录 一、一图概览 二、表格操作 三、内容操作 四、单元格操作 五、Pandas实现表格操作 六、常见场景示例 一、一图概览 ​ ​本文主要对openpyxl库的常用表格操作进行了梳理&#xff0c;熟练的运用后可极大地提升工作效率。 二、表格操作 #创建一个表格sheet.xlsx #…