当前位置: 首页 > news >正文

尚品汇-首页三级分类实现-nginx静态代理生成的静态页面(二十六)

目录:

(1)问题详解

(2)首页商品分类实现

(3)修改web-all模块

(4)页面渲染

(1)问题详解

(2)首页商品分类实现

前面做了商品详情,我们现在来做首页分类,我先看看京东的首页分类效果,我们如何实现类似效果:

思路:

  1. 首页属于并发量比较高的访问页面,我看可以采取页面静态化方式实现,或者把数据放在缓存中实现
  2. 我们把生成的静态文件可以放在nginx访问或者放在web-all模块访问

(3)修改web-all模块

修改pom.xml

 <dependencies>
<dependency><groupId>com.atguigu.gmall</groupId><artifactId>service-item-client</artifactId><version>1.0</version></dependency><dependency><groupId>com.atguigu.gmall</groupId><artifactId>service-product-client</artifactId><version>1.0</version></dependency></dependencies>

由于商品分类信息在service-product模块,我们在该模块封装数据,数据结构为父子层级

商品分类保存在base_category1、base_category2和base_category3表中,由于需要静态化页面,我们需要一次性加载所有数据,前面我们使用了一个视图base_category_view,所有我从视图里面获取数据,然后封装为父子层级

视图包含三级分类的所有数据

数据结构如下:json 数据结构

[{"index": 1,"categoryChild": [{"categoryChild": [{"categoryName": "电子书", # 三级分类的name"categoryId": 1},{"categoryName": "网络原创", # 三级分类的name"categoryId": 2},...],"categoryName": "电子书刊", #二级分类的name"categoryId": 1},...],"categoryName": "图书、音像、电子书刊", # 一级分类的name"categoryId": 1},...
"index": 2,"categoryChild": [{"categoryChild": [{"categoryName": "超薄电视", # 三级分类的name"categoryId": 1},{"categoryName": "全面屏电视", # 三级分类的name"categoryId": 2},...],"categoryName": "电视", #二级分类的name"categoryId": 1},...],"categoryName": "家用电器", # 一级分类的name"categoryId": 2}
]

二级: 

三级:

ManageService接口

/*** 获取全部分类信息* @return*/
List<JSONObject> getBaseCategoryList();

 ManageServiceImpl 实现类

com.alibaba.fastjson

三级分类视图: 一级,二级分类有重复的,三级分类没有重复的

发现有重复数据,需要去重:

使用distinct一次只能去重一个字段

 

使用分组去重,但是分组后,就不好获取其他数据了

所以最后是在java中利用api处理重复数据了

stream中的API有一个可以实现分组

 Map<Long, List<BaseCategoryView>> category1Map  =baseCategoryViewList.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));

一级分类:

二级分类:

 

三级分类:没有重复的不需要分组

 

@Override
@GmallCache(prefix = "basecategoryList:")
public List<JSONObject> getBaseCategoryList() {// 声明几个json 集合ArrayList<JSONObject> list = new ArrayList<>();// 声明获取所有分类数据集合List<BaseCategoryView> baseCategoryViewList = baseCategoryViewMapper.selectList(null);// 循环上面的集合并安一级分类Id 进行分组  value 是一级分类对应的所有数据Map<Long, List<BaseCategoryView>> category1Map  = baseCategoryViewList.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));//定义一级分类的序号int index = 1;// 获取一级分类下所有数据for (Map.Entry<Long, List<BaseCategoryView>> entry1  : category1Map.entrySet()) {// 每一个entry 是一个键值对,key 一级分类的id value一级分类的所有数据// 获取一级分类IdLong category1Id  = entry1.getKey();// 获取一级分类下面的所有集合List<BaseCategoryView> category2List1  = entry1.getValue();//category2List1.get(0).getCategory1Name() 一级分类的名字,一级分类的名字都是一样的,随便获取一个JSONObject category1 = new JSONObject();category1.put("index", index);category1.put("categoryId",category1Id);// 一级分类名称category1.put("categoryName",category2List1.get(0).getCategory1Name());// 变量迭代index++;// 循环获取二级分类数据Map<Long, List<BaseCategoryView>> category2Map  = category2List1.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));// 声明二级分类对象集合List<JSONObject> category2Child = new ArrayList<>();// 循环遍历for (Map.Entry<Long, List<BaseCategoryView>> entry2  : category2Map.entrySet()) {// 获取二级分类IdLong category2Id  = entry2.getKey();// 获取二级分类下的所有集合List<BaseCategoryView> category3List  = entry2.getValue();// 声明二级分类对象JSONObject category2 = new JSONObject();category2.put("categoryId",category2Id);category2.put("categoryName",category3List.get(0).getCategory2Name());List<JSONObject> category3Child = new ArrayList<>();// 循环三级分类数据category3List.stream().forEach(category3View -> {JSONObject category3 = new JSONObject();category3.put("categoryId",category3View.getCategory3Id());category3.put("categoryName",category3View.getCategory3Name());category3Child.add(category3);});// 将三级数据放入二级里面category2.put("categoryChild",category3Child);// 添加到二级分类集合category2Child.add(category2);}// 将二级数据放入一级里面category1.put("categoryChild",category2Child);list.add(category1);}return list;
}

控制器ProductApiController

/*** 首页数据获取三级分类信息* @return*/
@GetMapping("getBaseCategoryList")
public Result getBaseCategoryList(){List<JSONObject> list = manageService.getBaseCategoryList();return Result.ok(list);
}

 

 成功的添加到了Reids缓存

封装远程调用:  

service-product-client添加接口

ProductFeignClient
/*** 获取全部分类信息* @return*/
@GetMapping("/api/product/getBaseCategoryList")
Result getBaseCategoryList();

降级函数 

ProductDegradeFeignClient
@Override
public Result getBaseCategoryList() {return Result.fail();
}

(4)页面渲染

 

 

创建indexController: 

页面模版渲染

第一种缓存渲染方式:

package com.atguigu.gmall.all.controller;@Controller
public class IndexController {@Autowiredprivate ProductFeignClient productFeignClient;@GetMapping({"/","index.html"})public String index(HttpServletRequest request){// 获取首页分类数据Result result = productFeignClient.getBaseCategoryList();request.setAttribute("list",result.getData());return "index/index";}
}

可以额外添加功能:我们这里没做 

 

第二种:生成页面,nginx做静态代理方式:

 

 @Autowiredprivate TemplateEngine templateEngine; @GetMapping("createIndex")
@ResponseBody
public Result createIndex(){//  获取后台存储的数据Result result = productFeignClient.getBaseCategoryList();//  设置模板显示的内容Context context = new Context();context.setVariable("list",result.getData());//  定义文件输入位置FileWriter fileWriter = null;try {fileWriter = new FileWriter("D:\\index.html");} catch (IOException e) {e.printStackTrace();}//  调用process();方法创建模板templateEngine.process("index/index",context,fileWriter);return Result.ok();
}

将生成的静态页面与css 放入html 中即可!

 

页面生成了不能直接访问,他需要css,js..

复制项目里的css..

 

然后再双击index,就可以看了:

nginx先试用Windows版本的nginx 

 修改本地的nginx配置文件:添加:

 把生成的静态页面放到nginx目录下:

启动nginx 

直接访问nginx的端口号:

就可以通过nginx实现代理访问静态资源 ,使用nginx他抗并发的能力非常强

 

相关文章:

尚品汇-首页三级分类实现-nginx静态代理生成的静态页面(二十六)

目录&#xff1a; &#xff08;1&#xff09;问题详解 &#xff08;2&#xff09;首页商品分类实现 &#xff08;3&#xff09;修改web-all模块 &#xff08;4&#xff09;页面渲染 &#xff08;1&#xff09;问题详解 &#xff08;2&#xff09;首页商品分类实现 前面做了…...

对象存储及其相关概念介绍

对象存储是一种用来描述解决和处理离散单元&#xff08;这些离散单元被称作为对象&#xff09;的方法的通用术语。以下是关于对象存储的详细解析&#xff1a; 一、基本概念 定义&#xff1a;对象存储&#xff0c;也叫做基于对象的存储&#xff0c;是一种将数据以对象的形式进…...

TypeScript 研发系列

#TypeScript 编写HTML 游戏...

三维世界,一图打尽!Matplotlib带你玩转3D绘图,让数据跳舞的魔法棒!

1. 引言 嘿&#xff0c;亲爱的数据探险家们&#xff01;你们是否曾梦想过&#xff0c;在二维的屏幕上&#xff0c;让数据跳出束缚&#xff0c;翩翩起舞&#xff0c;展现它那迷人的三维身姿&#xff1f;今天&#xff0c;就让我这位自封的‘数据魔术师’&#xff0c;带你解锁Mat…...

计算机常识与NOIP历史-CSP初赛知识点整理

真题练习 [2021-CSP-J-第2题] 以下奖项与计算机领域最相关的是&#xff08; &#xff09;。 A.奥斯卡奖 B.图灵奖 C.诺贝尔奖 D.普利策奖 [2017-NOIP-第7题] 中国计算机学会于( )年创办全国青少年计算机程序设计竞赛。 A. 1983 B. 1984 C. 1985 D. 1986 [2018-NOIP-第5题…...

代码随想录算法训练营第二天 | 209. 长度最小的子数组、59. 螺旋矩阵 II

目录 209. 长度最小的子数组1、题目描述2、思路3、code4、复杂度分析 LC59 螺旋矩阵 II1、题目描述2、思路3、code4、复杂度分析 209. 长度最小的子数组 题目链接&#xff1a;209 1、题目描述 给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于…...

鼻咽癌综述

小罗碎碎念 本期推文主题&#xff1a;鼻咽癌综述 这篇文章提供了一个全面的综述&#xff0c;探讨了鼻咽癌&#xff08;NPC&#xff09;的关键研究进展&#xff0c;包括病理机制、治疗、筛查和生物标志物的发展。 文章首先强调了NPC在特定地理区域的流行情况&#xff0c;并讨论了…...

中国AI PC行业研究报告

核心摘要&#xff1a; 2020-2023年中国笔电出货量呈下降趋势&#xff0c;PC厂商亟需从产品形态、软硬技术、需求场景等角度寻求新的增长机会。而随着大模型、生成式AI技术的到来&#xff0c;其强大的数据处理、学习泛化与内容生成能力&#xff0c;高质效加速了各行各业人工智能…...

Mybatis实战:图书管理系统(笔记)

前言&#xff1a;如果在接口的声明方法中鼠标右键没有Test的单元测试。 你的鼠标光标问题&#xff1a;要在花括号范围内&#xff01;&#xff01;&#xff01;&#xff01; 数据库表是应⽤程序开发中的⼀个重要环节, 数据库表的设计往往会决定我们的应⽤需求是否能顺利实现, 甚…...

win11 amd64 python安装matplotlib、pytorch报错记录

win11 amd64 python matplotlib 安装报错记录 安装时 错误是 metadata-generation-failed 查看上面的具体报错原因&#xff0c;来自&#xff1a; Files\Python\Python3_10_11\Include: linker input file not found: No such file or director注意Python 的路径中最好不要有…...

Python写UI自动化--playwright(等待页面加载机制)

很多情况下&#xff0c;我们都需要等待页面加载到一定程度才能进行下一步操作&#xff0c;而这个度该怎么操作&#xff0c;这篇文章就来详细讲一讲 目录 expect_popup() wait_until参数 "load" commit: "domcontentloaded" "networkidle"…...

书籍将整数字符串转成整数值(5)0804

题目 给定一个字符串str&#xff0c;如果str符合日常书写的整数形式&#xff0c;并且属于32位整数的范围&#xff0c;返回str所代表的整数值&#xff0c;否则返回0。 举例 str“123” 返回 123 str“023” 因为023 不符合日常的书写习惯&#xff0c;所以返回0 str“A13” …...

【2024年华数杯C题老外游中国】(完整题解+代码+完整参考论文)

请问 352 个城市中所有 35200 个景点评分的最高分&#xff08;Best Score&#xff0c;简称 BS&#xff09;是多少&#xff1f;全国有多少个景点获评了这个最高评分&#xff08;BS&#xff09;&#xff1f;获评了这个最高评分&#xff08;BS&#xff09;景点最多的城市有哪些&am…...

全球氢化双酚A (HBPA)市场规划预测:2030年市场规模将接近1330亿元,未来六年CAGR为2.7%

一、引言 随着全球化工行业的持续发展&#xff0c;氢化双酚A (HBPA)作为重要的化工原料&#xff0c;其市场重要性日益凸显。本文旨在探索HBPA行业的发展趋势、潜在商机及其未来展望。 二、市场趋势 全球HBPA市场的增长主要受全球化工行业增加、消费者对高性能化工产品要求提高…...

【C++】异常处理:深度解析与实战精髓,不容错过的编程秘籍

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;C从入门到精通 目录 &#x1f680; 前言&#xff1a;C语言传统的处理错误的方式 一&#xff1a; &#x1f525; C异常概念二&#xff1a; &#x1f525; 异常的使用 2.1 &#x1f4d6; 异常的抛出和…...

智能指针的循环引用 是什么 怎么引起的

智能指针的循环引用 是什么 怎么引起的 智能指针的循环引用&#xff08;Circular Reference&#xff09;是指两个或多个对象之间的共享指针相互引用&#xff0c;导致这些对象永远不会被释放&#xff0c;从而引发内存泄露。主要发生在使用std::shared_ptr时&#xff0c;因为它们…...

Stegdetect教程:如何用Stegdetect检测和破解JPG图像隐写信息

一、Stegdetect简介 Stegdetect 是一个开源工具&#xff0c;专门设计用于检测图像文件&#xff08;JPG格式&#xff09;中的隐写信息。Stegdetect 可以检测多种常见的隐写方法&#xff0c;比如 JSteg、JPHide 和 OutGuess 等。 二、使用Stegdetect检测图像隐写 官方描述&#…...

Co-Detr

参考&#xff1a;https://www.bilibili.com/video/BV1Sh4y1F7ur/?spm_id_from333.788&vd_source156234c72054035c149dcb072202e6be 之前的detr正样本数量少&#xff0c;匹配不平衡。 主要修改两个地方&#xff1a;encoder和decoder。 1.在encoder之后加入RPN&#xff0c;a…...

校园选课助手【1】-项目整体架构从此开始

项目背景 随着高校招生规模的不断扩大&#xff0c;学生选课需求日益增长。为提高选课效率&#xff0c;降低学生选课压力&#xff0c;本项目旨在开发一款校园选课助手软件。 项目目标:开发一款具有以下特点的校园选课助手软件&#xff1a; 易用性&#xff1a;界面简洁&#xff…...

椭圆曲线加法运算

1. 定义 椭圆曲线 (Elliptic Curve) 不是函数&#xff0c;而是一条平面曲线&#xff0c;其方程是定义如下&#xff1a; y 2 x 3 a x b y^2x^3axb y2x3axb 其中&#xff0c;判别式 Δ − 16 ( 4 a 3 27 b 2 ) ≠ 0 \Delta -16(4a^327b^2)\neq 0 Δ−16(4a327b2)0。判别…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...