尚品汇-首页三级分类实现-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一级分类的所有数据
        // 获取一级分类Id
        Long 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()) {
            // 获取二级分类Id
            Long 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 {

    @Autowired
    private ProductFeignClient productFeignClient;

    @GetMapping({"/","index.html"})
    public String index(HttpServletRequest request){
      // 获取首页分类数据
       Result result = productFeignClient.getBaseCategoryList();
      request.setAttribute("list",result.getData());
      return "index/index";
  }
}

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

 

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

 

 @Autowired
 private 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他抗并发的能力非常强

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵俺第一专栏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值