第九章 Freemarker 详情页数据静态化

Freemarker 语法

文章静态化技术 与 Freemarker

进阶篇!开启!

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图1

1 什么是静态页面技术?

详情页现在还是 html 格式的。我们这个页面现在是“动态页面”。当前页面中的标题,内容这些,都要是发送请求到后端进行获取,返回以后才显示在页面上的
如果是静态页面的话,【不需要经过后端请求】就能打开。对于一些 媒体网站,电商商品详情页一般都会采用静态化技术

2 静态化优势

SEO的意思是“可以被搜索引擎收录”,那么搜索时被查询到的概率就更高(这块理论自己去补补);
加速用户访问:因为能最先展示文章的主体部分,这些部分不会经过后端发送啥的.
降低数据库压力:降低了数据查询压力.

3 模板引擎技术 实现 静态化

我们使用 Freemarker,比 Thymeleaf 兼容更多的技术栈.
Thymeleaf 是 springboot 官方推荐的模板引擎。

FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
模板编写为FreeMarker Template Language (FTL)。它是简单的,专用的语言, 不是 像PHP那样成熟的编程语言。 那就意味着要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。

4 页面静态化的过程

模板需要对应的文件:*.ftl。这个的话需要通过 yml 文件进行配置。
还需要一些动态数据,这些数据需要从redis,mongodb中得到。这些数据放入模板类中。
最终,通过 freemarker 结合这两部分,“把动态数据生成到 ftl 中去”,从而形成“静态的html”,此时不再包含动态数据。

之后可以先看看示例代码怎么操作的。当然最后主要还是应用到 详情页。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图2

5 Freemarker官方站点

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图3


创建并显示模板ftl:基于Freemarker写一下基本配置和 hello world。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图4

一、引入相关依赖

选择2.2.5 release(和springboot版本匹配)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图5
版本号(顶级工程中)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图6
依赖(放在article模块)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图7
下载依赖:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图8

二、模板页创建与配置

(1)创建

article 中 resources 中新建一个包 templates(叫这个主要是后面yml中配置路径时不用自己改了),里面创建模板文件:
模板页本质和html差不多。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图9

(2)页面框架

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图10

(3)介绍 freemarker 语法构成

<#—这种就是注释.
(具体见下图注释)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图11

(4)yml文件中配置 freemarker

在spring下面配置:44-48
字符集utf-8.
内容类型默认是 text/html

后缀默认是ftlh,我们设置成 .ftl
模板加载路径:(这个路径点击进入查看源码时得到,这也解释了之前resources里为啥包名叫这个)

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图12

三、模板页测试

1 编写测试方法:当前项目搞一个controller,作为测试:(注释如图)

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图13

路由地址我们假设为 free(@RequestMapping注解中),访问路径 /hello。
方法返回“模板页的路径地址”,所以是string类型,return只要是模板也的前缀即可,后缀我们刚才配置过了
数据要绑定到 model 才能在前端渲染,暂时理解为request。model中属性名称得和模板也中表达式名称对应:模板页是there,所以 model这里也是there。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图14

2 测试(11:50)

(1)如图输入路径:localhost:8001/free/hello
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图15
结果不是 “慕课网….”,而是stu、
原因在于使用了注解 @RestController。该注解作用下,给前端回传的都是字符串,我们方法返回的 路径 它搜不到,它直接给搞成 json 返回给前端了。(其实没太懂)

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图16

把8行这个注解改成 @Controller 即可。

(2)重测:

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图17

==>注意:当前输出的渲染是在“服务端”进行的,并没有输出html。这块后面再深入。

输出对象

上节课是“字符串在模板页中的展示”。
本节课学习“对象在模板页的展示”。

1 创建参与测试的类

老师实现放了两个类在model的pojo包中:spouse 和 stu
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图18

spouse是stu的属性,“配偶”的意思
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图19

2 对象 构建入 model 中.

controller类
重新写个测试方法,这个方法就是负责给stu类把属性都设置好。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图20
写好这个类后,在/hello方法中调用,这样就能把信息都存进model。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图21

3 模板页构建好

你要是把类已经放入了model中,这里 .属性 时就会弹出提示框。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图22

写好后如下:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图23

4 测试1

(1)报错1:日期类型有点问题
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图24
修改,进行日期类型转换:通过一个?来串联一个formate来格式化,25行
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图25
重测:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图26
(2)错误2:已育信息有点问题,boolean类型的.
还是类型转化问题.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图27

修改如下:这里 是 否 yes no 都行

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图28
重测:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图29

(3)测试输出嵌套的对象:
28补充
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图30

测试:(已于这里是老师改成false了)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图31

输出list和map

本节课继续学习 freemarker 语法。
之前输出了 字符串 和 对象.
本节开始学循环输出 list/map

1 Stu类中构建list和map
如下18 19,写完了生成一下get set
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图32

2 controller 中填充 list 和 map.
这个方法存3个list:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图33
这个方法存3个map:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图34
调用这俩方法:47 48
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图35

3 模板页中输出:
输出时,利用到循环指令,如下:
循环中还可以写一些文本标签;
list标签中article是别名.
map的话,key都不同,我们要先得到key,所以map标签里通过 ?keys as key 的方式得到 key 命名别名。然后输出的时候按图中格式放入key,就可以输出对应的value了。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图36

4 测试(8:00)

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图37

指令 if

1 编写模板页输出内容
(1)判断与某个字符串关系时
用 单引号.

(2)与integer.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图38

设置的值还是用之前的:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图39

(3)与booean值

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图40

(4)与对象
之前都是判断基本属性,这里拿一个“属性类spouse”来判断.
84行.
??代表“判空”.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图41

2 测试
(1)测试(1/2)
(结果在最下面)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图42

(2)测试(3)
最下边
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图43

(3)测试(4)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图44

页面静态化

示例:结合动态数据生成静态html(代码见老师笔记)

根据之前的内容,freemarker的基本语法 算是都演示过了。
本节课的话,主要是演示本章第1节提到的:【模板+动态数据,通过freemarker生成静态html】.
我们数据就基于stu这个类,模板也是之前用的stu的那个。

1 构建freemarker生成文件的位置

(1)配置文件中
去yml文件中写:76-78。
对于win系统,这里要写盘符:盘符:/路径
(??没像之前一样配置路径??)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图45

(2)controller中
18-19:通过 @Value注解 把路径的值传进去.
(这3级的关系就是yml中配置的关系。???后面了解下怎么通过这个注解读到yml属性的吧?)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图46

2 编写文件生成方法

返回一个ok,意思是在页面上提示一下生成成功即可。
这个返回和前几节返回模板路径的意思不同的。
(1)环境配置
Contuguration 是 freemarker 包下的.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图47

具体如下:class里的 / 代表根目录。
32行的这个路径就是我们之前提到的win中要单独写的路径(??win的话是不是写法在这不一样啊???)
32这里形参要求是File.

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图48
写完了测试一下:
34 35这sout一下,输出如下:测试完了注释掉.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图49

(2)得到现有ftl文件

(3)动态数据获取
model就调用咱们刚才写的makemodel方法模拟从数据库写入数据了.
然后这里要在方法里补充一下这个model形参,之前没有写。

3 融合,生成html

这里就要用到我们在 1 (2)中写的 freemaker文件生成的位置 这个属性了(23行)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图50

步骤如下:47-54
上来先判断下存在不。htmlTarget就是本节一开始写的 生成路径.
out是一个输出流,形参用 路径+文件名+后缀 拼接,然后通过process生成文件。生成后记得把这个 writer流关掉。

(java输入输出还不是很熟啊,后面复习一下!!)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图51

4 测试(12:20)

(1)报错1:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图52
这里就可以看到41的uft-8写错了,写成uft-8了.

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图53

(2)报错2:
这里说了模板页16行有问题.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图54
因为controller方法是我们新写的,所以there没在当前方法赋值.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图55
在当前方法也赋值即可
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图56

(3)错误3
ok了
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图57

有输出,但是文件有点问题,我们想让它在html这个文件夹下创建,结果因为这里少写了了 / 导致识别目录失败,直接拼接了。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图58
改错如下:52这里加个File.separator,根据OS加 \或者/.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图59

(4)重测

目录对了
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图60

双击打开:和之前一样.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图61

打开看看代码:之前写的表达式都没有了
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图62

获得tlf:改写详情页为模板tlf

之前都是演示,本节课开始实操。
咱们主要静态化“文章详情”页面.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图63

之前还是用 文章 id 动态访问的,后面我们直接把这个 id 作为静态文件的名字拼接串之一.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图64

现在呢,最主要的是“修改页面中的数据”

一、修改前端页面:如何把 动态页面 改成 模板页?

1 修改路径

(自己不想做前端,可以直接把老师i的前端文件拷贝到自己tomcat配置的地方)
==>不对,【现在不是放在tomcat】!现在是放到老师这写的这个a文件夹,这个路径本节后面写方法的时候涉及到了,看后面的。tomcat的事情后面再说!!

专门创建一个文件夹a,代表article,赋值一个 detail.html 进来,修改这个。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图65

因为detail.html的路径变了,所以里面 js css 相应url位置也得修改!
老师已经改完了,过一遍:
①cs和js的路径
9-14注释掉,改成16-28
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图66
下图同理.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图67
② 图片路径:例如 48 49
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图68
如下
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图69

③ 修改完测试一下
输入如下url:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图70

2 修改为模板

(1)赋值文件到项目中
复制这个.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图71
复制到我们前几节课测试用的地方:顺便后缀改成 ftl
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图72

(2)修改页面中内容:
articleDetail是原来动态页面中一个用来保存信息的重要对象,可以去之前基础篇的前端页面查看。我们动态信息就用这个获取.
① titile 改成表达式
38
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图73
② 重新获取 页面 id
285-288注释掉.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图74
不再需要通过url路径获取articleId。之后id直接作为文件名。我们重新获取,如下:这里getPageName在原detail 188行,用来获得页面名称。
290-294
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图75

③ 涉及 articleDetail 的都改改,用 ctrl+f 一个个去找.(9:50)


至此,模板基本改好

后面拿到动态的文章数据,和这个模板议结合,就可以生成静态页面了。
最后生成的html放到如下位置即可:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图76
==>老师建议直接拷贝他的,减少我们改这个的失误率,毕竟涉及前端.

获得动态数据:文章详情ftl生成静态页面

之前提到了:生成静态页面需要 “模板页(上节课)” + “动态数据”。本节课就获取“动态数据”,并且输出静态页面.
当然,文章两种发布形式:自动审核后发布 + 手动审核后发布
本节处理:手动审核后发布
自动审核 我们之前注释掉了,后面再说怎么弄。
————————————————————————-

1 配置 静态页面“生成位置”

(1)配置文件

老师这里可以拷贝路径,win好像上面能拷贝.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图77
我们新增一个节点即可,就按上节课选的那个a文件夹就行.
定义好后,目录如下:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图78

(2)controller中 定义 生成方法

① 跟之前例子一样,写一个属性,用@Value获取配置中的生成路径。
155 156
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图79

② 静态化文件方法1:拷贝之前例子中方法,修改第一波
首先,不需要返回值了,return也删掉。之前写返回值纯粹为了测试。
形参不用model了,用文章id作为形参即可.

方法名改了.

171 文件名改改,是deatil不是stu。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图80

③ 静态化文件方法2: 编写远程调用代码
根据文章id获取文章详情的方法,不再当前controller中。去ArticlePortalController中去找detail方法。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图81

其中的VO的数据我们需要拿到页面中渲染.、
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图82

现在有个问题:我们“不能在当前controller直接调用 当前工程中 另外一个controller”,除非是一个 重定向(??复习?)。

==>即使在同一个服务中,我们也应该“发起一个http请求,获取另一个controller的方法”。
如下:基本和之前写的远程调用一致,找一个复制过来改改(6:10).

(restTemplate得去BaseController中把private改成public)

191-204
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图83

④ 静态化文件方法3: 通过远程调用,调用另一个controller的方法detail()——根据文章id得到文章详情
调用方法,进行相应修改。(小细节挺多,看不懂来再回来听)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图84

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图85

(3)controller中 调用 生成方法

① 确定方法的业务位置.
打开articleController,有个doReview方法.
这个是admin调用的接口(复习一下业务逻辑).
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图86

134 135 这里,如果“审核成功”的话,就该生成静态页面了!(whywhywhy!复习下业务)
??是审核完就可以发布文章,所以需要生成文件,然后把文件发出去的意思???

② 调用(2)中写好的controller方法:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图87

2 测试(11:00)

得去审核通过一篇文章才能执行方法.

(1)报错1:
没生成文件.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图88
发现:序列化有问题
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图89

修改:VO这里15行
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图90

重测:重新写一个文章并审核.
成功:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图91

(2)
拷贝这个(就是文章id):
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图92

直接输入如下:即直接动态显示!
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图93
这就是渲染出来的 静态页面。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图94

看看生成文件的前端:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图95

(3)错误3:无法跳转
页面左侧这里点击作家名字没跳转。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图96

修改:修改生成的静态文件:384这里需要加 ../。
因为url发生了变化,所以跳转的时候这要改改.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图97

当然,改生成文件没啥用,我们改生成方法:
348行,生成的时候就加上.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图98

3 其他细节.

(1)页面是静态部分,但是【评论是动态的,我们没有静态化!】
(??这里第一次还是挺难接受的,怎么一部分静态一部分动态??)
还是可以发表评论

(2)
当然,文章两种发布形式:自动审核后发布 + 手动审核后发布。
本节处理:手动审核后发布
之前把 自动审核注释了,所以目前所有文章必须手动审核。下节课去改。
==>意思是“自动审核”部分这块内容自己写嘛???

文章阅读量单独获取并展示

1 问题分析

(1)什么问题?
页面左上这里有个“阅读量”,一直是0,这节课处理一下。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图99
其实redis中是有数据的:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图100
生成的文件中,阅读量这里应该要动态生成,而不是让freemarker生成静态的。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图101
(2)怎么造成的?怎么解决
阅读数本来在detail接口动态获取,静态化以后不会被动态调用了,静态化以后这块数据就写死了。
评论区能动态是因为评论区部分没有静态化。
==> 247-248这两行代码要提取出来,做一个单独的接口!

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图102

2 代码编写

(1)创建controller接口:51
这里定义的时候不像之前定义grid了,返回integer即可
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图103
(2)实现类controller
就拿之前247/248几行复制过来即可.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图104

3 修改前端页面

(1)现在已经生成的html接口改一下,测试接口方法是否正确
(一串前端的东西,不懂)
82行:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图105
266增加一行:默认为0.(什么动态绑定啥的,都忘了)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图106

写一个方法:349开始
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图107

299加上这个方法调用,别忘了写this
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图108
测试:阅读量有了.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图109

(2)刚才的修改补充到 ftl 中去(6:50)

函数
生命周期的调用
默认的属性
插值表达式
重新生成并测试:….

静态化解耦

梳理生产端消费端与中间gridfs关系


详情页的静态化已经完成,但是从业务上来讲,“耦合度太高”。

一、静态化高度耦合(见老师笔记)

说白了就是 后端 前端 放在两个服务器上。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图110

部署方式如下:
(1)后端生成HTML,上传到 GridFS文件系统.
(OSS这种也行吗,内部使用GridFS更好一些)(没懂,不知道这个“内部”是什么意思??)
(2)后端通知前端,应该去获取HTML
(3)前端接受到后端的通知.(前端服务器这里有一个迷你后端,专门接受后端的消息)
(4)前端根据请求,去GridFS下载HTML文件
(5)根据下载的路径,利用Ngix或者tomcat进行“路径虚拟化”,这样,HTML就可以在浏览器端访问到.

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图111

==>本节课完成(3)中,“前端服务器迷你后端”的构建

二、“前端服务器迷你后端”的构建(4:50,具体见视频)

1 新建maven工程
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图112

html这个服务专门生成HTML.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图113

(1) 补充依赖

(2) yml文件复制过来,微调
port:8002
数据库数据源都不要了mapper这些都不要了.

2 搭建后端框架
(1)构建application启动类

包名如下.
类复制其他服务的即可,基本一样.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图114
(2)构建测试controller
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图115

(3)测试(8:00)
测试前关闭数据库的自动类型装配。因为这个工程中数据库的依赖还在,但是我们把数据库的配置都删掉了,所以为了避免sb自动配置时报错,我们把这块禁用。
虚拟机里面mongodb也要启动,不然会报错!

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图116
这里给项目改名,增加辨识度.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图117

运行成功:
(这里怎么体现接受后端的消息??还没编写,只是搭了个架子是吗???)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图118

生产端存储html到gridfs并关联文章表

零、

① mongoFileId 就是文件对应的 主键 id。 (本节课,article模块)
② GridFS中的数据要和数据库中的文件关联. (本节课,article模块)
③ 这里下载的路径就是我们tomcat的路径. (下节课,article-html模块)

(前端=消费端【article-html模块】 后端=生产端【article模块】)
(后端生产html,前端消费html)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图119

一、【上传】生成html并上传,拿到mongoFileId

复制文章生成HTML的方法,小改一波,让他变成上传html到GridFS的方法。

(1)修改文件名,然后把生成html的代码都去掉,我们直接上传0,无需生成。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图120

(2)使用freemarker自带的工具类和方法,把 html 转成 string

211行.
(198这里,后面要改成string返回值)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图121
(2.5)调用方法
159注释了,160调用方法进行测试.
(此时还没有返回值,暂时用void)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图122

(3)测试1:打印(2)中得到的string(4:50)

输出的就是我们“静态化后的html”.

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图123

(4)上传到GridFS

用这个 apache 的 io 包.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图124
如下:217。写完这个我们先去处理GridFS
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图125

(5)GridFS配置类

我们曾在files模块中写过:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图126
拷贝到article中:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图127

article-html也拷贝:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图128

(6)注入GridFS,并调用上传方法,得到对应的mongoFileId

(sout代码测试完了记得注释掉)
这个方法可以传入inputStream,正好和(4)调用IO工具包生成的流匹配上。如下这个方法:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图129
其中String s这个形参是:取名。用当前文章id+后缀来命名。
上传完毕之后,得到ObjectId,属于MongoDB的包。这个我们后面就拿来做关联。把这个 id 返回。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图130

(7)修改审核成功时的代码

164
调用我们刚才写的方法,拿到mongoFileId。
然后准备编写 文件关联保存 的代码。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图131

二、【关联】本地 和 GridFS 的文件

以前讲数据库表设计时,这个mongo-file-id一直没用,现在用来做关联。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图132

(1)service层接口

41
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图133

(2)service层实现

116
别忘了加事务。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图134

(3)回到controller,发起调用

166
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图135
(???12:30这里提到两个service什么事务,什么关联啥的,没听懂??什么调整到同一service中?==>问答区好像 有讨论这个的,后面看看)

(4)测试(12:50)

mongodb中的:ID列的末尾9e7f
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图136

数据库中的:末尾9e7f
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图137

—————————————————-
至此,article服务的代码写完了.(生产端)
下节课写article-html的代码。(消费端)

消费端从gridfs下载HTML到tomcat

上节课article服务的代码写完了(生产端):上传 与 关联
本节课写article-html的代码。(消费端):从GridFS下载。

三、【下载】构建 下载 接口.

1 api 工程中,在article包下构建接口

(api这块,不区分article-html和article了)
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图138

编写controller接口

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图139

2 article-html 工程中实现 消费端接口

先把 gridFSBucket 注入进来.
(1)
选择第二个这个方法来下载啊:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图140
(2)
输出流这里就是“存储下载文件的路径”。
最后要抛出异常(接口之间没抛出,去补一下)、

34 行 separator 左侧是路径,右侧是文件名加后缀。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图141
(3)
其中articlePath通过配置 和 属性注解来获取。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图142
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图143

(4)补充注释,补充返回值
返回值这里,返回状态码。
当然你用apache包下的也行,用springframworker的也行,两者的枚举类的名称不太一样,都代表 200。图中显示的是spring包的写法,这个比较推荐。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图144

3 生产端 调用接口

去articleController中编写。

(1)编写调用方法

方法传入 mysql的文章id 和 Mongodb中的id 即可。
url需要重新配置域名,如下:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图145
(??url的规则还要去复习下呀)
方法见177行:184 这里通过 url 调用了消费端的方法。
这里老师写错了,html 和 download 之间少了/
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图146

(2)调用:
170 171行

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图147

4 测试(12:30)

发表文章后,tomcat这有文件就说明对了!
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图148

撤回删除文章,删除gridfs文件以及html(作业)

1 业务介绍
html又声称,也应该有销毁:
如下图:已发布的文章可以“撤回/删除”
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图149
不仅要改数据在数据库中的状态,还要把文件从前端删掉!
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图150

2 流程简介

(1)点击“撤回/删除”时,拿到文章信息,包括mongodbId.
(2)消费端:根据mongodbId,从gridFS中删掉对应文章.
(emmm,是不是没提 修改 生成端文章状态)


小结:
本章主要完成了 服务器解耦。

接口还是用restTemplate去写的,这种方式的话,耦合度较高。前端多个节点时,就得修改。(没太懂)

==>下一章mq,实现接口层面的解耦
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图151

如何保证详情页静态化后的高并发性能?(作业)

第十章 RabbitMQ异步解耦与延迟队列

一、MQ介绍与安装

接口解耦需求

==>为实现“接口解耦”,使用 RabbitMQ.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图152

1 回顾上一章节
我们 生产端 通知 消费端 是使用的“Rest 请求调用”.
这样做耦合度较高。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图153

2 从一个故事理解 消息队列
图中模式存在以下几个缺点:
(1)生产者得一个个批发商打电话,批发商多的话,效率很低.
(2)新增批发商的话,还得去记录新的批发商(即后端代码补充新的参数)
==>代表耦合度高
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图154

3 优化思路
如何优化?如何做到通知一次,让其他批发商看到,并自己来拿货?
==>微信群:生产者发通知,批发商 监听 通知。从而实现解耦。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图155

4 接口解耦的过程:

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图156

RabbitMQ 概述 & MQ 模型

1 常见的MQ
RMQ和Kafka有什么区别呢??去了解一下?

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图157

2 什么是RabbitMQ?
AMQP是协议:应用之间通信,分布式中多见
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图158

3 应用场景:

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图159

4 RabbitMQ模型

channel 就是通道,用来建立连接。可以有很多个,可以发很多消息。
注意,消费者这里和MQ是“双向”的,因为消费者需要“监听”MQ。
Exchange是交换机,可以理解为 路由/映射。不同的Exchange可以把消息放入不同的队列。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图160

集成MQ

MQ整合到项目中去。

一、引入相关依赖和配置

1 api 工程中的 pom 文件:
25行.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图161
导入好了可以查看.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图162

2 在需要使用mq的项目中,进行相关的配置.
(1)生产者 article 服务
打开yml文件,spring节点下配置:49-54

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图163

① host:代表mq的安装位置,填Linux的ip即可。(默认是localhost)

② port:5672
③ username 和 password:用可视化界面里的admin.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图164
④ virtual-host:
上图可视化界面就有virtual host,打开如下图,默认有 /,代表根目录.
imooc这个是老师自己创建的,还可以自己创建,图片下面那个add的那块就可以。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图165
测试添加了一个dev的,我们就用的这个!
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图166

(2)消费者 article-html 服务
刚才(1)的那几行复制过来即可:34-39

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图167

3 启动观察/测试(5:50)
交换机Exchange 和 消息队列Queue 没有创建,目前还看不出来啥.

二、

创建交换机和队列

紧接上节.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图168
二、创建 交换机Exchange 和 队列Queue.
交换机Exchange 和 队列Queue 是独立的,你创建好了还要把它们绑定在一起。
把当前 降锁(说的啥,听不清)的操作写在 api 中。

1 配置文件
路径如下,创建一个配置类.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图169

2 起名
final属性(也没解释为啥).
15和18
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图170

3 创建 交换机
放入 spring 容器。注入容器时,其名称也用刚才创建的名字。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图171
① 注意,导入的包是:spring 的 amqp.core.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图172
② 这里这几个代表“不同模式”。我们使用的就是 topic模式 。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图173
③ 形参就是我们刚才命名的交换机的名字。

后期有可能会讲。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图174

④ durable 就是 持久化。对于 消息队列 可以设置 true 或者 false。
⑤ build就是构建。

4 创建队列
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图175

5 介绍创建成功后,可视化界面的显示情况
交换机创建成功的话,这里会默认创建7个交换机。
下着这dev就是我们要创建(啥时候创建的?为啥已经有了?)。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图176

队列成功创建时,这里会显示:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图177

(暂未测试)

三、绑定 交换机Exchange 和 队列Queue.
这张MQ模型很重要,牢记。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图178

1 绑定方法
如下:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图179
(1) 绑定类型有很多,我们用amqp.core的这个作为返回值。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图180
(2) bind为绑定方法。这里形参是“队列对象”,而非一个string。因此,为了能在bind中使用,我们通过当前方法的形参把 queue 传进来!交换机形参同理。
同时,加上注解 @Qualifier才 能正确传给bind方法,表示去容器中拿这两个bean。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图181
(3)to就是 和什么绑定 的意思,这里选择形参为 交换机 的。

(4)通过with指定匹配规则
形参为 routingKey,当作是 路由/映射。这里暂时写 article.* 。
==>下节课具体讲这个 routingKey.

(5)noargs() 方法执行绑定,源码中,这个方法就是返回一个Binding对象
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图182

2 测试(12:20)
install 和 启动 都没问题.
其实现在没有执行方法,可视化界面没有什么 显示。

创建生产者,配置路由规则

四、创建生产者,设置符合要求的路由规则

生产者应该属于article这个项目。

1 RabbitMQ 路由规则 routing key 介绍

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图183

2 使用HelloController进行测试
(1)创建
这个过程主要是“生产者 发送消息到 交换机”,然后“交换机 可以通过 一定的路由规则,把信息存入相应的 队列 中”。

类外补充注解RequestMapping,性质为producer(干啥的忘了)
注入rabbit模板,在hellow方法中写一个发送方法,直接调用 rabbitTemplate 中的 convertAndSend 方法即可。
形参1:要发送到的交换机的名称。

形参2:路由规则,待会写这个。(这个规则,必须符合上节课中,“队列绑定交换机的过程中的 routingKey ”!)
形参3: 说明。object类,一般放一个字符串即可。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图184

上图中30行的规则,必须符合43行的这个“article.*”。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图185
最后测试前,别忘了给方法加上路与朴:

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图186

(2)测试(7:50)
调用生产者发送.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图187

可以在可视化界面这里查看:
total 就是 1 了。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图188

交换机:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图189

进入queues板块,找到下面的get Messages,就可以看到了
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图190

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图191

….
(12:00)更改路由,多个发送请求,再测试。
(14:30)解绑之前的队列,再测试

消费者接收消息处理业务

五、创建消费者
在html模块中处理消费者。
1 消费者监听MQ
(1)创建一个新的类

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图192

(2)补充注解.
通过RabbitListener指定要监听的队列.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图193

(3)
形参String payload,Message是amqp.core包下的.

因为消息作用于payload的载体

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图194

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图195

(4)测试打印payload(3:20)
13行打断点。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图196

思考:这里我们得去在网页调用生产者url,这里才会打印?还是说,不调用生产者url,根据queue已有的就会打印了?
==>只要Queue有消息,就会监听!而不是非要再调用一次生产者的 url 才行。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图197
(5)关键信息:receivedRoutingKey
这里这个Routing Key就是很关键的消息了,通过这个就可以识别是什么类型MQ,然后就可以编写对应的处理代码
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图198

2 根据监听到的 receivedRoutingKey 编写匹配的处理代码
关闭刚才编写的 消费者。取消断点,继续处理。

(1)获取receivedRoutingKey

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图199

(2)根据不同的receivedRoutingKey进行不同的处理
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图200

(3)测试
内容打印到了控制台!
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图201

——————————————————————-
至此,生产端口,消费端口,解耦模型完成!

三、

文章静态化HTML与删除

前面几节课实现了如下 RMQ的模型,现在我们要通过这个等模型真正去解决我们项目中静态HTML 上传 下载 删除 的问题!

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图202

本节先优化这块代码:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图203

1 生产者
复制一份这个方法,我们重新写!
(1)编写生产者方法
注入mq的模板类.
之前object形参我们写了一个string,现在我们这里把文章id和mongodbId拼接到一起写上去,方便识别。 当然了,假如你要传递的对象多起来后,完全可以新建一个实体类,把信息都放进去,然后把这个实体类对象传进来!

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图204

(2)调用生产者方法
176
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图205

2 消费者
(1)
这里呢,我们这里新建一个类,把监听、下载、删除的这些操作写在新的Controller类中,将其作为一个组件,注入bean中。然后我们在上节课中rabbitMQconsumer中注入这个类!就可以通过不同的routingkey调用不同的方法了

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图206
毕竟这个controller的方法就是已经写好的下载、删除文件的方法。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图207

(2)
rabbitMQconsumer中注入(1)中的controller。
回顾生产者的 routingkey :article.download.do;生产者的objext :文章id,对应mogodbId(对应消费者的paload)
因此,这里消费者这里匹配上这个规则。25行。
然后payload就是生产者的object,是含有 文章id,对应mogodbId 的字符串。这里直接分割,分别获取这两个id。27,28行。
这两个参数就是controller中下载方法所需的 id。32行。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图208

3 测试(6:10)

发个文章,审核通过测试以下。结果是成功的。
文章也下载了,IDEA也接受信息并打印了。

4 更改前端
代码老师准备好了,你切换即可:74切成75。
这样从冬天查询文章,变成了直接打开静态文章。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图209

5 删除功能自己写。

四、延迟队列

延时队列需求与安装配置

一、为什么项目中要应用 延时队列?
(1)
延时消费:之前是消费者监听到就可以处理,现在是监听到以后,等设置的时间到了才处理。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图210

(2)之前业务中的弊端
项目中有一个“自动发布文章”,我们之前写过:

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图211
这个就是具体的实现,这是一个全表扫描,只要发布时间小于当前时间,代表可以发布,而不是定时的状态。(??懵了?)。既然是全表扫描,数据量一大必然对数据库造成冲击。同时还有时间精度不够,查询性能低等缺点。

因此,之间 定时任务发布 实际由很多问题。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图212
==>我们使用 延时队列 KO 这个问题!

二、RabbitMQ 延时队列 功能 安装与配置(5:20)

实现延时队列

也需要“构建交换机、队列,并设置绑定关系”!

一、延时队列的配置

1 创建延时队列配置类,并修改交换机和对立的名字!

重新建个个列,交换机的名字和对立的名字都改掉!
创建方法中对应的变量名都改好!
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图213

2 调用delayed方法,增加延时队列功能!

25行.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图214

3 队列绑定交换机

改下名字
然后改下routingKey

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图215

4 补充:方法名相同导致容器内的冲突

之前和这里绑定方法都是binding,而且都@Bean了,这样可不行!记得改方法名!
38
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图216

二、实现 生产者 的延时队列

1 生产者发送延时消息

还是在helloController中编写:
重写一个接口,基本和之前一样,如下:

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图217

2 选择重载方法,构建所需的处理器

MessagePostProcessor,这是个 消息发布的处理器,这里可以设置“发送模式”、“延时时间”等
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图218

回到controller类中,定义一下这个 MessagePostProcessor,重写一下它里面这个方法。里面这个DeliveryMode就是发送模式,我们选了 持久模式。
随后,再设置时间,单位ms。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图219

3 补充形参
86
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图220

三、消费者 监听 延时队列
1 创建消费者

(这一块录制的音质不太好。为什么这里 消费者和生产者要放到一个项目中去????不是要解耦嘛?????)
这里直接复制过来了,还没有重命名
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图221

2 修改消费者代码
这里简单sout一下即可
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图222

为了方便后面测试,生产者这里也sout一下:90
这样就可以计算时间差了。
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图223

四、测试(9:10)

之前设置了5s,这里确实是5s.
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图224

上节课模拟了延时队列的演示,熟悉了延时队列的使用流程。
本节课实际运用这个功能,利用它完成“定时发布文章”。

1 业务分析

发文章的时候可以选择 定时发送:
我们需要用 “定时时间 - 当前时间 = 延时时间”

一、生产端
2
先找到article 模块的 ArticleController 的 createArticle方法。
这个方法内部调用过一个service:94

进入这个service。再insert文章以后,补充相应的判断。

进入if里的代码,我们把上节课延时队列演示的代码copy过来,进行修改。

主要包括MessagePostProcessor处理器的设置,convertAndSend。复制过来以后如下:

3 计算延时时间
通过BO得到计算所需的两个时间点,然后就可以计算了。

93-96计算。

98调用了一个API计算,便于我们待会看测试结果。

108这个延时时间已经设置好了。

4 重新约定routingKey
生产者那边重新声明:

消费者这边定义。
message就传文章id即可。

二、消费端
主要是修改状态为“即时发布”
之前定时任务是这么写的:全表查询来修改。
==>现在需要一个修改单条记录状态的service方法

1 service层
(1)接口
25行

(2)实现
181行开始:

2 controller层
注入 service,调用方法.
articleId 这么写,不仅可以方便后续拓展业务的调用,同业也更加清晰。

三、测试(10:20)

———————————————-
延时任务执行完后没有生成html,这块需要作为作业自己去完善。


实现文章的定时延时发布

上节课模拟了延时队列的演示,熟悉了延时队列的使用流程。
本节课实际运用这个功能,利用它完成“定时发布文章”。

1 业务分析

发文章的时候可以选择 定时发送:
我们需要用 “定时时间 - 当前时间 = 延时时间”
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图225

一、生产端
2
先找到article 模块的 ArticleController 的 createArticle方法。
这个方法内部调用过一个service:94

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图226

进入这个service。再insert文章以后,补充相应的判断。

进入if里的代码,我们把上节课延时队列演示的代码copy过来,进行修改。

主要包括MessagePostProcessor处理器的设置,convertAndSend。复制过来以后如下:

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图227

3 计算延时时间
通过BO得到计算所需的两个时间点,然后就可以计算了。

93-96计算。

98调用了一个API计算,便于我们待会看测试结果。

108这个延时时间已经设置好了。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图228

4 重新约定routingKey
生产者那边重新声明:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图229笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图230

消费者这边定义。
message就传文章id即可。

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图231

二、消费端
主要是修改状态为“即时发布”
之前定时任务是这么写的:全表查询来修改。
==>现在需要一个修改单条记录状态的service方法

笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图232

1 service层
(1)接口
25行
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图233

(2)实现
181行开始:
笔记B:Spring Cloud 进阶 Alibaba 微服务体系自媒体实战(慕课网实战项目) - 图234

2 controller层
注入 service,调用方法.
articleId 这么写,不仅可以方便后续拓展业务的调用,同业也更加清晰。

三、测试(10:20)

———————————————-
延时任务执行完后没有生成html,这块需要作为作业自己去完善。



第十三章 ES 优化项目

文章查询

粉丝列表

粉丝画像.

Redis 拓展

END