整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

新手建站 无需购买服务器10分钟快速部署你的静态网页

新手建站 无需购买服务器10分钟快速部署你的静态网页

里云云开发平台重磅推出开源应用中心,聚合最热门的开源应用,让你像安装app一样快速上线一个网站。面向新人和持续活跃的开发者用户推出上线激励加油包,最高100元无门槛代金券免费送,现在体验还能够领取年轻人的养生神器,桌面不锈钢保温杯!

聚合最热门的开源应用

开源应用中心聚合了目前最热门的前端开源应用模版,让大家真正可以做到像安装APP一样来上线一个网站。目前已经支持最热门的前端框架,包括Vue.js、React、Nuxt.js、Next.js、AntDesign等,还有内容管理平台Hexo、Docusaurus、VuePress、Sapper等。使用部署开源模版非常适合您的以下场景:

  • 个人学习:轻松创建个人主页、博客等网站,边部署边学习。
  • 协同开发:创建信息管理系统、CMS等前端项目,多人协同维护开发。

云开发平台同样面向广大的开源作者征集应用,对于热门的应用我们能够提供现金激励、以及流量曝光等扶持。

开源应用一键同步一键部署

阿里云云开发平台前端应用部署功能旨在为前端开发者改善工作环境,优化前端开发和部署体验。同时还可以结合云开发平台云原生的架构能力和主机应用的部署能力,让前后端应用能够更高效地协同。

  • 操作简单:无需购买服务器、配环境、手动上传文件等,云开发平台都可以帮你自动操作,包括在需要时随时一键上线/下线。
  • 使用零成本: 支持GitHub和云效的Codeup仓库,快速将仓库的代码进行构建部署。
  • 免费资源扶持: 免费提供临时的测试域名,对于新用户和持续活跃的用户提供免费的云资源加油包。
  • 无数量限制: 没有使用的repo数量和应用数量的限制, 不管是开源仓库还是自己账户下的repo,每一个代码repo都可以部署为一个静态网站。

简单几步使用云开发平台上线静态应用

1. 账号准备工作

  • 你需要一个阿里云账号,并使用阿里云账号登录云开发平台 (https://workbench.aliyun.com/),按照提示创建团队,点击同意协议。没有阿里云账号就在登录页面注册一个继续登录。
  • 拥有Github账号 (https://github.com/),没有就注册一个。为保证最好的使用体验,请使用Chrome浏览器。
  • 未开通阿里云OSS的用户,点击链接 (https://workbench.aliyun.com/product/open?code=oss)开通OSS服务。OSS开通免费,有一定的免费额度,超过额度之后按量付费。

2. 创建应用

2.1 选择应用中心任意模版创建应用

  • 选择应用中心任意模版创建应用。如果您之前没有使用过云开发平台,会出现云资源授权管理的选项,往下拉出现直至同意授权的字样,点击「同意授权」后出现授权成功,点击进入「下一步」。

  • 绑定GitHub账号。授权完成后选择来源仓库为GitHub,按照提示点击去绑定,绑定GitHub帐号,登录后并点击Authorize AliyunWorkbench允许云开发平台构建、发布你的GitHub代码为可访问的网站。 绑定完成后返回应用创建页面,代码仓库按照默认「模板仓库」以及默认主干分支不用操作,并点击「下一步」。

  • 填写应用信息完成创建。填写必要的的应用信息完成创建(我们已提供默认配置),成功后进入到应用详情和部署界面。首次登录并没有可选所属生产线,点击右侧自动创建产品线即可。

2.2 使用自己的仓库应用创建

  • 选择自己仓库里需要部署的应用。除了可以使用应用中心的模版创建网站,云开发平台也支持使用本地代码或者开源代码创建静态网站。与通过模版中心的应用创建的区别在于,在绑定Gihutb之后选择“自己的仓库”,找到上一步自己创建的GitHub仓库及master分支。然后在应用详情页面根据以上的步骤继续填写即可。

  • 设定部署配置。当部署的是您自己的代码仓库时,开发平台需要您根据具体代码进行简单配置来部署成功:
    1. 编写build.sh:代码从源码,经过npm打包编译等过程,到生成为纯粹HTML/CSS/JS静态文件的全过程的shell指令,需要被完整填写到发布分支根路径下的build.sh文件中,例如:

不知道如何操作?您也可直接点击一次“部署”按钮,之后,对默认生成的build.sh内容进行任意修改:

b. 填写静态文件相对目录:在build.sh执行后,从代码生成出的静态文件所在的相对目录,需要被填写到“部署配置-资源路径”中。

Tip:例如React应用(如图),一般会填写“./build”;Vue应用则一般为“./dist”。

c. 调整配置:当您完成上述步骤后,发现自己的代码仍然部署错误时,需查看排查部署日志,对上面的build.sh和部署资源路径进行修改。常见的几种部署错误情况如下:

3. 在日常环境部署站点

  • 一键进行应用部署。在应用详情页面点击日常环境的「部署」按钮进行一键部署,部署状态变成绿色已部署以后可以点击访问部署网站查看效果。

  • Dinosaurs网站日常环境部署好了。日常环境的测试域名也是可以访问的,点击访问已部署网站按钮会出现一个弹出,点击弹出上的立即访问就能够访问已经部署好的站点了。在部署完成后,可以继续本地编码,并将代码push到应用的“基本信息”中对应的代码仓库内。

4. 配置自定义域名在线上环境上线

  • 配置线上环境自定义域名。在功能开发验证完成后要在线上环境进行部署,在线上环境的「部署配置」-「自定义域名」中填写自己的域名。例如我们添加一个二级域名 company.workbench.fun 来绑定我们部署的前端应用。然后复制自定义域名下方的API网关地址对添加的二级域名进行CNAME配置。

  • 配置CNAME地址。复制好 API网关域名地址后,来到你自己的域名管理平台(此示例中的域名管理是阿里云的域名管理控制台,请去自己的域名控制台操作)。添加记录的「记录类型」选择「CNAME」,在「主机记录」中输入你要创建的二级域名,这里我们输入「company」,在「记录值」中粘贴我们之前复制的 API网关域名地址,「TTL」保留默认值或者设置一个你认为合适的值即可。

  • 在线上环境部署上线。回到云开发平台的应用详情页面,按照部署的操作,点击线上环境的「部署按钮」,部署完成以后就在你自定义的域名进行了上线。CNAME 生效之后,我们输入 company.workbench.fun(示例网址) 可以打开部署的页面。至此,如何部署一个应用到线上环境,如何绑定自己的域名来访问一个线上的应用就完成了,赶紧部署自己的应用到线上环境,用自己的域名玩起来吧 ;)

原文链接:https://developer.aliyun.com/article/829641?utm_content=g_1000314028

本文为阿里云原创内容,未经允许不得转载。

索引擎和聚合类新闻App之所以有源源不断的新内容供予用户浏览,原因就在于有网络爬虫技术的加持。网络爬虫的应用对于用户来说,是一大福利——我们可以从一个搜索引擎轻松搜索到各个领域的信息。但是,对于原创方来说,就涉及到版权被侵犯的问题了。工具理性,但不意味着操持工具的人就可以假借“工具理性”肆意侵犯他人的合法权益,网络爬虫技术的应用还应该要在法理之内。

一、初识爬虫

工作的时候,想要查找“产品设计”,可以直接在搜索引擎上输入内容,就可以直接找到数以百万计的资料。

上下班路上,刷新闻类APP的时候,只要愿意,就会有源源不断的新的信息,足够刷一路的时间。

搜索引擎和(大多数)新闻类APP都不自己生产内容(虽然有些平台孵化了自己的内容,但也只占整个平台内容的很少的一部分,更重要的是,成本非常高)。

那么,他们的大量的内容从哪里来?

“我们不生产内容,只是内容的搬运工”,将互联网上的内容“搬运”到自己的服务器上,这就是爬虫。

首先,我们需要了解一下互联网的结构。

互联网上的内容数以亿计,虽然很复杂,但说白了就是一张大网,网上的每个节点就是一个网页,连接网页的超链接(Hyperlinks)相当于线,线把所有的节点连接在一起,形成了一个复杂的网。

通过点击超链接的文字或者图片,就可以跳转到对应的网页。爬虫可以自动访问到每一个网页,并把网页的内容保存下来。

世界上第一个网络爬虫由麻省理工学院的学生马修·格雷(Matthew Gray)在1993年写成,之后的爬虫尽管越来越复杂。

比如:可以实现更快的访问速度、访问更多的网页、更好的将网站内容解析出来。但爬虫的基本原理是一样的,都主要包括三个部分:访问网页链接,下载网页内容,解析网页内容。

爬虫的工作过程与我们查找网页的过程是一样的。

比如,我们想要查一下豆瓣上最新的电影:首先,在浏览器地址栏输入网址链接https://movie.douban.com/,之后,浏览器会跳转到豆瓣电影。最后,我们就可以找到当前热映的电影。

同样的,一个最简单的爬虫三步就可以爬取一个网页——首先,访问这个网页,之后,把网页内容下载下来,最后,对下载的内容进行解析。

二、7行代码爬取豆瓣电影

最简单的爬虫三步就可以爬取一个网页,那么要写多少行代码呢?

我们写一个爬虫,爬取豆瓣的“一周口碑榜”,只要7行代码!

这里我们使用Python语言,至于为什么选择Python语言,会在后面交代清楚,如果不懂Python也没有关系,了解爬虫是如何工作的就可以了。

代码如下:

import requests from lxml

import html url=’https://movie.douban.com/’ # 1、需要爬数据的网址

page=requests.Session.get(url) # 2、访问网页

tree=html.fromstring(page.text) # 3、解析网页的过程

result=tree.xpath(‘//td[@class=”title”]//a/text’) #3、解析网页的过程

print(result) # 打印出结果

在Python环境中运行这几行代码,就可以获取“一周口碑榜”了,结果如下:

[‘迦百农’, ‘绿皮书’, ‘驯龙高手3’, ‘速成家庭’, ‘阿丽塔:战斗天使’, ‘肤色’, ‘死亡天使’, ‘黎明墙’, ‘小小巨人’, ‘出·路’]

其中最关键的是解析网页内容,主要是(‘//td[@class=”title”]//a/text’)这行代码,大多数人可能对比较困惑。

这涉及到HTML网页的结构,可以把网页理解成一个文件夹,打开一个文件夹,会发现子文件夹,子文件夹或许还有文件夹。通过打开一个个文件夹,最终找到需要的数据。

  1. //td :这个相当于大目录;
  2. [@class=”title”]:这个相当于小目录;
  3. //a :这个相当于最小的目录;
  4. /text:这个是提取其中的文字内容。

至于是怎么写出来这行代码的,可以通过在网页空白处点击右键,查看源代码,就可以找到对应的td、class=”title”、a等标识符。

大多数程序员写爬虫选择python的理由很简单.

首先,python有很多的库,可以直接调用,比如:上面的代码就引入了requests、lxml库,分别实现访问网页、对网页结构解析。有开源的库,就直接调用,避免重复造轮子。

其次,python写起来很方便,配置也简单,短短几行的代码,就可以直接运行了,如果使用C或者Java,可能配置环境就要老半天。

三、一个简答的爬虫系统

把上面的每个步骤分别实现(模块化),就可以构成一个简答的爬虫系统。

使用URL(可以理解为网址链接)管理器管理所有的网址链接,使用HTML(可以理解为网页内容)下载器下载网页内容,使用HTML解析器对下载的内容解析,再加上数据存储模块、控制整个爬虫的调度模块,就构成了一个简单的爬虫系统。

爬虫基本架构

更具体的说,URL管理器负责管理所有的网址链接,记录下哪些URL已经爬取了,哪些还没有爬取。如果爬取过了,就要避免再次下载,如果没有,就要加入队列,等HTML下载器下载。

HTML下载器可以从服务器下载整个网页的内容,从URL管理器中获取未爬取的网址链接,之后,访问这些网页链接,下载网页。

HTML解析器负责解析下载好的网页,主要有两个任务:一方面,解析出需要的信息,比如上文的“一周口碑榜”;另一方面,解析出新的URL链接,交给URL管理器,继续下载,这个功能在上面的“7行代码”没有实现。

数据存储器实现存储数据的功能,将HTML解析器解析出来的信息存储起来,否则每次使用都要下载,会浪费大量的时间。图片、文档之类的文件可以直接保存到服务器上,文字类的可以通过数据库存储起来。

爬虫调度器作为系统的大脑,负责统筹其他四个模块的协调工作。

无论是大型的还是小型的爬虫虽然在设计细节,性能上有所不同,但都不会脱离这五个模块。

四、更深入的考虑

乍一看,每个模块实现起来都很简单,但细想,似乎每个模块都要考虑很多东西。

1. 初始的网址链接如何获得

7行代码爬取豆瓣电影,直接访问网址链接(https://movie.douban.com/)就可以爬取“一周口碑榜”。对稍大一些的爬虫系统或者商用爬虫,就要有更多的考虑了,在保证获取充足信息的同时,也要保证下载的质量。

对搜索引擎公司而言,要尽可能包括互联网所有的信息。对垂直领域,更多的偏向业务类信息,比如:对新闻类的APP,主要包括一些新闻网站、政府网站等,对Github这类的编程网站,他们可能就不感兴趣。

巧妇难为无米之炊,初始的网址链接基本要靠人工凭经验获取,比如:新闻类的APP,他们的初始URL列表里可能就包括新浪、网易、搜狐等门户网站,也包括各个级别的政府网站,还有人民网、新华社、人民日报等媒体的网站。

2. 如何确定哪些网页已经下载过了

当一个页面下载完成后,从这个网页中提取出其中的网址链接,把它们添加到等待下载的队列中,就可以获得更多的网址链接。

如果一个网页已经下载过了,重新下载,会消耗大量的时间,并占用存储空间。更要命的是,如果一直重复下载,就可能陷入死循环。

那么,如何知道这网址链接是不是已经下载过了?

对于小型爬虫,可以使用列表存储下载过的网址链接,当有新的网址链接的时候,先查找这个列表中有没有该网址链接。如果有的话,就不用插入,如果没有的话,就插入列表,等待访问下载。

对于大型爬虫,有成百上千个“小爬虫”(更加专业的名词叫做分布式爬虫),分布在不同的服务器上,同时爬取网址链接,就要考虑更多的东西。

比如:不同爬虫之间的分工和通信,如何共同维护上述的列表。

当数据很大的时候,就要考虑分布式、通信、存储、带宽等每个环节的限制,无论哪个环节没有做好,都有可能成为系统的瓶颈,这就像是木桶效应中的短板。

数据量增加10倍,之前的代码可能要重写了,工作量可能就要增加100倍,这也是量变引起质量的一个很好的例子。

在计算机领域,这样的例子随处可见,当数据增大到一定量级,原有的算法很可能无法继续使用,需要重新开发,随之而来的是加班、DEBUG以及延期上线。

3. 页面的解析

爬取豆瓣电影的“一周口碑榜”,需要研究网页的源代码,并编写对应的解析代码。但是网页的结构不同,用这个代码爬取知乎,解析不到任何内容。

以新闻类的APP为例:一个好的新闻类APP需要爬虫数以亿计的网页,并把里面的文字、视频、图片分别解析出来,难度可想而知。

好消息是一部分网站会遵守RSS规范(遵守RSS规范的网页结构和代码都有相似性,以便于订阅器获取主要信息),一种类型的爬虫就可以爬取大量这种类似的网页。但大部分的网站的结构,都是不同的,这需要算法工程师花费大量的时间和精力做解析工作。

五、 反爬虫

新闻类APP通过爬虫,获得大量的优质资源,读者也乐意在一个平台上看到所有的内容,但“被爬取”的网站就不太高兴了。对于大多数依靠广告收入的网站,没有了流量,连生存都成了问题,更别说盈利了。

一些自成体系的平台,比如:大型电商平台,他们希望所有的用户在自己的平台上查找信息,所有的商家在自己的平台上吸引卖家(广告费可不能付给搜索引擎),同样不希望爬虫的骚扰。

搜索引擎希望爬取更多的信息,优质的内容提供商又不希望被爬虫骚扰,利益冲突难以调和,于是产生了Robots协议来解决这个问题。

Robots协议网站服务器的一个声明,通常是保存在网站根目录下的一个TXT格式的文件,网站通过Robots协议告诉搜索引擎:哪些页面可以抓取?哪些页面不能抓取?

当爬虫访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在,爬虫就会按照该文件中的内容来确定访问的范围;如果该文件不存在,所有的爬虫将能够访问网站上所有没有被口令保护的页面。

我们使用搜索引擎,经常会看到“由于该网站的robots.txt文件存在限制指令(限制搜索引擎抓取),系统无法提供该页面的内容描述”,就是源于这个协议。

值得注意的是:Robots协议是国际互联网界通行的道德规范,并没有强制性约束力。

一些“没有道德”的爬虫同样会爬取有robots.txt限制指令的网站,这时候就需要一些技术来实现反爬虫了。

最常见的有三种方式:

1. 网站会根据IP地址访问的频率确定是不是爬虫

每个电脑都有唯一的IP地址,每个爬虫也有唯一的IP地址,当电脑或者爬虫访问网站的时候,网站会记录这个IP地址。如果同一个IP短时间多次访问同一个网站,这个网站可能会倾向于认为这是个爬虫,会采取一些措施。

当然,这在反爬虫的同时,也会给用户带来一些不好的体验。

相比之下,一些比较优秀的网站或者APP,会根据用户点击频率、时间间隔等信息,判断是不是爬虫或者误点击,之后再确定是否需要验证。

更好的用户体验背后,是更大的开发成本,更长的开发周期。

2. 网站也可以根据用户请求的Headers来判断是不是爬虫

当我们使用浏览器访问网站的时候,浏览器会自动在访问请求上添加一些信息,比如:浏览器采用的编码方式、使用的操作系统、浏览器版本等信息放在访问请求的最开始,作为Headers,但爬虫一般不会附加这些信息。

网站会根据是否存在Headers信息以及Headers信息的内容,判断对方是不是爬虫,有必要的话,就拒绝访问。

3. 动态页面的反爬虫

之前将的HTML网页都是静态的,随着HTML代码生成,页面的内容和显示效果就不会发生变化了。而动态网页则不然,动态网站是脚本语言(比如PHP)生成的,一些内容不是直接可见的,而是要运行一些脚本,才能看到。

网址后缀为htm、html、shtml、xml的网页是静态网页,而动态网页是以·aspx、.asp、.jsp、.php、.perl、.cgi等形式为后缀,并且在动态网页网址中有一个标志性的符号“?”,这些不同的后缀基本代表了网页使用的语言。

访问静态网页,只需要直接访问链接就可以了,访问动态网站,还需要执行一些特定的操作(比如点击),才能显示更多的内容,这就增加了爬取的难度,一些简单的爬虫就被拒之门外了。

介绍完三种主流的反爬虫的方式,最后要说的是:反爬虫技术也不是一劳永逸的,在反爬虫的发展过程中,爬虫也进化出了一系列反“反爬虫”的方式。

针对反爬虫验证IP机制,爬虫“进化”出了IP代理池,这样,爬虫就可以不断变换自己的IP地址,迷惑反爬虫。针对Headers验证,爬虫也会生成一个Headers信息,甚至针对动态页面,也会模拟浏览器的行为。

虽然如此,反爬虫在一定程度上提高了爬虫的成本,降低了爬虫的效率,就可以将一大部分爬虫挡在门外。

从爬虫与反爬虫的例子也可以看出:大多数时候,没有绝对的有效方式。提高对方的成本,让对方觉得代价太大,得不偿失,就是很好的解决问题的办法。

六、爬虫实现冷启动——胜利即正义?

上面讲了爬虫是怎么运行的,常见的反爬虫机制。最后,我们再讲一个爬虫的应用场景的例子,可以帮助我们更好理解爬虫。

冷启动是每一个产品经理、运营人员和创业者面临的重大问题。没有优质的内容,就吸引不了用户,没有大量的用户,就无法吸引优质的内容,就陷入了先有鸡还是先有蛋的悖论。

爬虫,低成本、快速地解决了这个问题!

“我们不生产新闻,我们只是新闻的搬运工”,通过爬虫,低成本、快速地爬取整个互联网的优质内容,并凭借海量数据,利用算法实现内容分类和个性推荐(个性推荐系统会在后序章节详细介绍),吸引大量的用户,最终通过广告变现。

事实证明,这是个非常成功的商业模式。而媒体平台和新闻网站雇佣大量编辑人员,花费大量时间、金钱写成的高质量内容,连说一声都没有,就这样被拿走了,这不是侵犯人家版权嘛!

于是,多家媒体联合发起侵权诉讼或抗议声讨,最终迫使这家新闻巨头支付版权费,但无论法律上、道德上有多少问题,都不影响这家公司商业成功的既定事实。

类似的事情同样发生在其他垂直领域。

一家新成立的技术博客平台,爬取竞争对手上的文章,迅速实现优质内容的聚合。如果原博客主发现了自己的文章被盗用了,新的平台就移交账号并看情况给予少许补偿。如果对方不乐意,就注销账号,当一切都没有发生过。凭借这种运营方式,顺利实现了冷启动。

短视频APP的后来者,也可以通过类似的方式,实现用户的积累和优质内容的聚合。

胜利即正义?

这似乎是过于武断的一个评价。

上述的视频APP做得太过分,引起公愤,最终不得不关闭自己的平台。

对于通过爬虫获取内容的平台而言,内容的获取也只是万里长征的第一步,通过运营手段减小生产内容的成本,通过利益共享激励优质内容的产生,通过技术减小信息成本吸引用户,更加任重而道远。

而版权,也始终是悬于头顶的达摩克利斯之剑。

本文由@linghu 原创发布于人人都是产品经理,未经许可,禁止转载

题图来自Unsplash, 基于CC0协议

pring Boot使用freemarker并且生成静态html页面

之前我介绍了在spring boot中使用thymeleaf模板,这次我会给大家介绍在spring boot中使用freemarker模板技术,同时利用freemarker生成静态html页面。生成静态html页面就能实现网站的静态化进而提高网站的访问速度以及提高SEO能力。

首先在pom.xml中添加依赖

添加依赖

<dependency>
 <groupId>org.freemarker</groupId>
 <artifactId>freemarker</artifactId>
 <version>2.3.23</version>
 </dependency>

application配置

在application.properties中添加freemarker的配置参数

##freemarker
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.enabled=true
spring.freemarker.suffix=.ftl
spring.freemarker.template-loader-path=classpath:/templates

Controller和ftl模板

下一步我们就建一个基础Controller类和配套的ftl模板

Controller类

package com.hw.myp2c.common.controller;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.io.*;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping("")
public class MainController {
 @GetMapping
 public String main(Model model){
 String w="Welcome FreeMarker!";
 Map root=new HashMap();
 root.put("w",w);
 model.addAttribute("w","Welcome FreeMarker!");
 return "test";
 }
}

可以看到很简单,跟之前的thymelefa和jsp的没有区别。

freemarker模板

<html>
<head>
 <title>Welcome!</title>
 <link rel="stylesheet" href="/bootstrap.min.css">
 <script src="/lib/jquery.min.js"></script>
</head>
<body>
<h1>Hello ${w}!</h1>
</body>
</html>

这样之后我们就能完成了基础freemarker的使用,更多的使用参见freemarker官方网站,这里不做过多的描述。

这里我们已经完成了标准的freemarker集成,下面我们将介绍如何利用freemarker生成静态html页面,直接上代码,作为演示我们还是在Controller中完成,在实际应用中我们可以按照自己的实际需要进行封装。

package com.hw.myp2c.common.controller;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.io.*;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping("")
public class MainController {
 @Resource
 Configuration cfg;
 @GetMapping
 public String main(Model model){
 String w="Welcome FreeMarker!";
 Map root=new HashMap();
 root.put("w",w);
 freeMarkerContent(root);
 model.addAttribute("w","Welcome FreeMarker!");
 return "test";
 }
 private void freeMarkerContent(Map<String,Object> root){
 try {
 Template temp=cfg.getTemplate("test.ftl");
 //以classpath下面的static目录作为静态页面的存储目录,同时命名生成的静态html文件名称
 String path=this.getClass().getResource("/").toURI().getPath()+"static/test.html";
 Writer file=new FileWriter(new File(path.substring(path.indexOf("/"))));
 temp.process(root, file);
 file.flush();
 file.close();
 } catch (IOException e) {
 e.printStackTrace();
 } catch (TemplateException e) {
 e.printStackTrace();
 } catch (URISyntaxException e) {
 e.printStackTrace();
 }
 }
}

利用freemarker生成静态页面我理解的流程是这样的

1.利用Configuration读取想生成静态页面的模板,这里是test.ftl

2.解析模板文件,并将模板中的${}!包含的参数替换成真实的数据

3.最终将读取了真实数据的模板生成相应的html文件,并写入指定目录

这样我们就完成了spring boot中使用freemarker模板,并且利用freemarker生成静态html文件