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

基于SpringBoot和Freemarker的页面静态化

页面静态化能够缓轻数据库的压力,还能提高页面的并发能力,但是网页静态化是比较适合大规模且相对变化不太频繁的数据。

页面静态化在实际应用中还是比较常见的,比如博客详情页、新闻网站或者文章类网站等等。这类数据变化不频繁比较适合静态化页面。该篇博客就是介绍博客详情页的页面静态化输出。

页面静态化实现

导入Jar

compile group: 'org.springframework.boot', name: 'spring-boot-starter-freemarker', version: '2.1.6.RELEASE'

配置文件

server:port: 8015servlet:context-path: /staticftl# freemarker静态资源配置
# 文件路径
spring:freemarker:tempalte-loader-path: classpath:/templates
# 关闭缓存,及时刷新cache:  falsecharset:  UTF-8content-type: text/htmlsuffix: .htmlmvc:static-path-pattern: /static/**

编写模板文件

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>${blog.title}</title>
</head>
<body>
<h1>${blog.title}</h1>
<h2>${blog.author}</h2>
<div>${blog.content}</div>
</body>
</html>

Freemarker还提供很多其他的常用的指令和函数,功能也是非常强大的。

页面输出

 /*** 输出静态化页面* @param root* @param id*/
public void productStaticPage(Map<String,Object> root, String id){Configuration config = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);config.setDefaultEncoding("UTF-8");//输出页面的全名String path = getStaticHtmlPath()+"/" + id + ".html";File f = new File(path);File parentFile = f.getParentFile();if(!parentFile.exists()){parentFile.mkdirs();}Writer out = null;try {//获取模板页面String templatePath =ClassLoader.getSystemResource("templates").getPath();TemplateLoader templateLoader=new FileTemplateLoader(new File(templatePath+"\\blog"));config.setTemplateLoader(templateLoader);Template template = config.getTemplate("detail.html");//输出页面out = new OutputStreamWriter(new FileOutputStream(f), "UTF-8");//处理数据template.process(root, out);} catch (Exception e) {e.printStackTrace();}finally {if(null != out){try {out.close();} catch (IOException e) {e.printStackTrace();}}}
}

通过Freemarker输出静态页面。

/*** 魔改的Freemarker的静态化页面输出地址* 不具备普遍性* @return 静态化页面输出地址*/
public String getStaticHtmlPath(){//Thread.currentThread().getContextClassLoader().getResource("templates").getPath()String path = this.getClass().getClassLoader().getResource("").getPath();if(path==null || path.length()==0){return "";}path=path.substring(0,path.indexOf("build"))+"\\src\\main\\resources\\static\\html";return path;
}

这个代码在实际应用是需要更改的,目前是在本机Windows中,且把静态化页面放到了项目目录中,其实更好的结果是将输出静态化页面放到Nginx服务器中,这样在并发性也更高,而且目录环境也更好解决。

本身使用Freemarker输出静态页面是比较简单的,上述关键代码再加上一些串联代码应该能正常运行了,其中需要注意的就是相关目录,里面涉及到一个模板目录,用于读取模板;一个输出页面目录,目前是使用SpringBoot并把static目录当做静态资源,所以需要把静态页面放入此目录,但是建议使用Nginx来做静态页面的服务器。

加入消息中间件和MongoDB数据库

我又加入了一点小功能,实现当我们将博客数据保存到MongoDB数据库中,使用ActiveMQ队列功能,异步将博客数据静态化到页面中然后输出。

引入Jar

compile group: 'org.springframework.boot', name: 'spring-boot-starter-activemq', version: '2.1.6.RELEASE'
# 需要引入如下Jar包,不然ActiveMQ的配置无法导入。
compile group: 'org.messaginghub', name: 'pooled-jms', version: '1.1.0'
compile group: 'org.springframework.data', name: 'spring-data-mongodb', version: '2.1.6.RELEASE'

配置文件

spring:data:mongodb:host: 127.0.0.1port: 27017database: staticftlactivemq:broker-url: tcp://localhost:61616#true 表示使用内置的MQ,false则连接服务器in-memory: false#true表示使用连接池;false时,每发送一条数据创建一个连接pool:enabled: true#连接池最大连接数max-connections: 10idle-timeout: 30000user: adminpassword: admin

使用MongoDB

import com.plf.learn.staticftl.bean.Blog;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;@Repository
public interface BlogRepository extends MongoRepository<Blog,java.lang.String> {
}

SpringBoot自带的封装MongoDB的操作,使得数据库操作变得非常简单。

使用ActiveMQ

发送队列消息

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Component;@Component
public class ActiveMQProducer {@Autowiredprivate JmsMessagingTemplate jmsMessagingTemplate;/**** @param destination   队列* @param message   信息*/public void sendMessage(String destination,String message){jmsMessagingTemplate.convertAndSend(destination,message);}
}

监听队列,将数据静态化到页面上

import com.plf.learn.staticftl.bean.Blog;
import com.plf.learn.staticftl.service.BlogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;@Component
public class BlogStaticFtlListener {@Autowiredprivate BlogService blogService;@JmsListener(destination="staticftl.blog")public void ListenBlogQueue(String message){String blog_id = message;//获取到博客信息Blog blog = blogService.getById(blog_id);Map<String,Object> map = new HashMap<>();map.put("blog",blog);//输出静态化页面blogService.productStaticPage(map,blog_id);}
}

上述代码即可实现,将博客文章保存到MongoDB数据库中,然后通过消息中间件消费输出静态化页面,即可直接访问静态资源。完整代码可访问我的Github。

相关文章:

基于SpringBoot和Freemarker的页面静态化

页面静态化能够缓轻数据库的压力&#xff0c;还能提高页面的并发能力&#xff0c;但是网页静态化是比较适合大规模且相对变化不太频繁的数据。 页面静态化在实际应用中还是比较常见的&#xff0c;比如博客详情页、新闻网站或者文章类网站等等。这类数据变化不频繁比较适合静态…...

给软件增加license

搞计算机的&#xff0c;都知道软件license,版权&#xff0c;著作权等。在商业软件中&#xff0c;常用的模式是一年一付&#xff0c;或者五年一付&#xff0c;即软件的使用权不是无限年限的&#xff0c;在设计软件的时候&#xff0c;开发者就需要考虑这个问题。要实现这个功能&a…...

vue中实现订单支付倒计时

需求 创建订单后15分钟内进行支付&#xff0c;否则订单取消。 实现 思路&#xff1a; 获取当前时间和支付超时时间&#xff08;在创建时间的基础上增加15分钟即为超时时间&#xff0c;倒计时多久根据自己的实际需求&#xff0c;这里为15分钟&#xff09;&#xff0c;支付超时…...

途乐证券-新手炒股快速入门教程?

随着互联网和金融商场的不断发展&#xff0c;越来越多的人开端重视股票商场。但是对于股市新手来说&#xff0c;怎么快速入门炒股成为了一个困扰他们的难题。以下从多个角度分析&#xff0c;提供一份新手炒股快速入门教程。 1. 了解根本概念 首要&#xff0c;股市新手需求了解…...

【冒泡排序及其优化】

冒泡排序及其优化 冒泡排序核心思想 冒泡排序的核⼼思想就是&#xff1a;两两相邻的元素进⾏⽐较 1题目举例 给出一个倒序数组&#xff1a;arr[10]{9,8,7,6,5,4,3,2,1,0} 请排序按小到大输出 1.1题目分析 这是一个完全倒序的数组&#xff0c;所以确定冒泡排序的趟数&#xff0…...

TypeScript 泛型的深入解析与基本使用

系列文章目录 文章目录 系列文章目录前言一、泛型的概念二、泛型函数三、泛型类四、泛型接口五、泛型约束总结 前言 泛型是TypeScript中的一个重要概念&#xff0c;它允许我们在定义函数、类或接口时使用参数化类型&#xff0c;增强了代码的灵活性和重用性。本文将深入探讨泛型…...

【Terraform学习】保护敏感变量(Terraform配置语言学习)

实验步骤 创建 EC2 IAM 角色 导航到IAM 在左侧菜单中&#xff0c;单击角色 。单击创建角色该按钮以创建新的 IAM 角色。 在创建角色部分&#xff0c;为角色选择可信实体类型&#xff1a; AWS 服务 使用案例:EC2 单击下一步 添加权限&#xff1a;现在&#xff0c;您可以看到…...

海国图志#1:这一周难忘瞬间,吐血整理,不得不看

这里记录每周值得分享的新闻大图&#xff0c;周日发布。 文章以高清大图呈现&#xff0c;解说以汉语为主&#xff0c;英语为辅&#xff0c;英语句子均来自NYTimes、WSJ、The Guardian等权威媒体原刊。 存档时段&#xff1a;20230731-20230806 乌克兰&#xff0c;波罗当卡 一名妇…...

【Android】okhttp爆java.lang.IllegalStateException: closed的解决方法

解决 java.lang.IllegalStateException: closed异常通常是由于OkHttp中的Response对象在调用response.body().string()后被关闭而导致的。 在代码中&#xff0c;在onResponse()方法中如果两次调用了response.body().string()&#xff0c;每次调用都会消耗掉响应体并关闭Respo…...

Django之定时任务--apscheduler

Django--定时任务apscheduler的使用 apscheduler定时任务的使用1、安装包2、配置settings.py3、在manage.py的文件同级目录下创建文件scheduler.py4、在项目的urls.py中调用这个定时计划5、然后启动项目 python manage.py runserver,在admin中查看就能看到你的定时任务及执行的…...

Spring Boot 项目应用消息服务器RabbitMQ(简单介绍)

一、背景 本章讲述的是在用户下单环节&#xff0c;消息服务器RabbitMQ 的应用 1.1 消息服务器的应用 在写一个电商项目的小demo&#xff0c;在电商项目中&#xff0c;消息服务器的应用&#xff1a; 1、订单状态通知&#xff1a;当用户下单、支付成功、订单发货、订单完成等…...

HBuilderX

HX 简介下载安装 简介 HBuilderX 是一款由 DCloud 开发的集成开发环境 (IDE)&#xff0c;主要用于前端开发和移动应用开发。它基于 Visual Studio Code 平台&#xff0c;针对 Web 开发、小程序开发、移动端开发等提供了丰富的功能和插件。 DCloud官网: https://www.dcloud.io …...

C数据结构与算法——常见排序算法时间复杂度比较 应用

实验任务 (1) 掌握常见比较排序算法的实现&#xff1b; (2) 掌握常用比较排序算法的性能及其适用场合。 实验内容 (1) 平均时间复杂度O(n2)和O(nlog2n)的算法至少各选两种实现&#xff1b; (2) 待排序的无重复关键字存放在一维整型数组中&#xff0c;数量为60000个&#xff…...

C++并发多线程--死锁问题及解决方法

1--死锁问题 死锁问题&#xff1a;两个线程访问资源时加锁&#xff0c;但都需要对方的资源才能执行释放锁&#xff1b; 代码实例&#xff1a;下面的代码中&#xff0c;当线程 1 使用 my_mutex1 上锁后&#xff0c;会继续使用 my_mutex2 进行上锁&#xff0c;若此时线程 2 已经使…...

【Spring】纯注解开发

1、简介 在Spring3.0升级了纯注解开发模式&#xff0c;使用Java类来代替配置文件&#xff0c;开启了Spring快速开发赛道。 2、定义bean Component Service Controller Repository 3、纯注解开发 使用Configuration声明一个配置类&#xff0c;使用ComponentScan来扫描作为bea…...

【算法心得】正确估计dfs时间复杂度;剪枝优化不怕重构

https://leetcode.cn/problems/verbal-arithmetic-puzzle/ 这题看到题&#xff0c;“表达式中使用的不同字符数最大为 10”&#xff0c;就觉得dfs就完事了&#xff0c;最多不过10!&#xff0c;10!才1e6&#xff0c;1e7这样。如果字符再少点&#xff0c;6! 7! 8!的&#xff0c;…...

通过网关访问微服务,一次正常,一次不正常 (nacos配置的永久实例却未启动导致)

微服务直接访问没问题&#xff0c;通过网关访问&#xff0c;就一次正常访问&#xff0c;一次401错误&#xff0c;交替正常和出错 负载均衡试了 路由配置检查了 最后发现nacos下竟然有2个order服务实例&#xff0c;我明明只开启了一个呀 原来之前的8080端口微服务还残留&…...

div输入框的文字超过指定行数用省略号表示css

实现效果&#xff1a;超过四行用省略号表示 实现方法&#xff1a; .text{overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 4; // 自定义行数-webkit-box-orient: vertical; }...

STM32 F103C8T6学习笔记5:定时器输出不同占空比PWM驱动舵机旋转角度

现在学习使用STM32 F103C8T6的定时器PWM模式&#xff0c;使用PWM驱动舵机转动不同角度&#xff0c;文章提供源码&#xff0c;测试工程&#xff0c;测试动态效果图。 目录 基础原理&#xff1a; 实验目标&#xff1a; 测试视频结果&#xff1a; 测试工程下载&#xff1a; 基…...

液体神经网络:LNN是个啥概念?

一、说明 在在人工智能领域&#xff0c;神经网络已被证明是解决复杂问题的非常强大的工具。多年来&#xff0c;研究人员不断寻求创新方法来提高其性能并扩展其能力。其中一种方法是液体神经网络&#xff08;LNN&#xff09;的概念&#xff0c;这是一个利用动态计算功能的迷人框…...

vLLM-v0.11.0保姆级教程:零基础3分钟部署,让大模型推理速度提升5-10倍

vLLM-v0.11.0保姆级教程&#xff1a;零基础3分钟部署&#xff0c;让大模型推理速度提升5-10倍 1. 为什么选择vLLM-v0.11.0&#xff1f; 1.1 大模型推理的痛点 在传统的大语言模型推理过程中&#xff0c;我们常常面临以下挑战&#xff1a; 显存利用率低&#xff1a;KV Cache…...

群晖NAS+Docker实战:手把手教你部署Llama 2打造私有化AI助手

1. 为什么要在群晖NAS上部署Llama 2&#xff1f; 最近两年&#xff0c;大语言模型&#xff08;LLM&#xff09;的火爆程度有目共睹。但大多数人都只能通过网页或API使用这些服务&#xff0c;不仅响应速度慢&#xff0c;还面临着隐私泄露的风险。而群晖NAS作为家庭和小型办公室的…...

Massa区块链终极资源指南:开发者、节点运营者与用户的完整工具清单

Massa区块链终极资源指南&#xff1a;开发者、节点运营者与用户的完整工具清单 【免费下载链接】massa The Decentralized and Scaled Blockchain 项目地址: https://gitcode.com/gh_mirrors/ma/massa Massa是一个去中心化且可扩展的区块链平台&#xff0c;为开发者、节…...

Gemma-3-12b-it多模态交互工具效果展示:菜单图片识别+多语言翻译生成

Gemma-3-12b-it多模态交互工具效果展示&#xff1a;菜单图片识别多语言翻译生成 1. 引言&#xff1a;当AI看懂菜单&#xff0c;还能帮你翻译 想象一下&#xff0c;你走进一家异国餐厅&#xff0c;面对一份满是陌生文字的菜单&#xff0c;完全不知道点什么好。这时候&#xff…...

细说杨乃武与小白菜案

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、案件二、精神分析学---心理防御机制三、关于我自己总结前言 一、案件 略&#xff0c;后面补 二、精神分析学—心理防御机制 在这个案件我主要关注县令和小…...

解锁B站直播自由:第三方推流工具深度技术解析

解锁B站直播自由&#xff1a;第三方推流工具深度技术解析 【免费下载链接】bilibili_live_stream_code 用于在准备直播时获取第三方推流码&#xff0c;以便可以绕开哔哩哔哩直播姬&#xff0c;直接在如OBS等软件中进行直播&#xff0c;软件同时提供定义直播分区和标题功能 项…...

PCIe C++代理实例化

为了能调用PCIe AVIP的C用户接口&#xff0c;先要在C仿真文件中对PCIe C代理做一个实例化声明。PCIe C代理负责两件事&#xff1a;从C仿真程序获得事务报文&#xff0c;并将其通过信号接口发送给BFM。从信号接口接收事务响应报文&#xff0c;并将其发送给C仿真程序。注意&#…...

跨平台资源下载终极方案:res-downloader如何破解多平台内容获取难题

跨平台资源下载终极方案&#xff1a;res-downloader如何破解多平台内容获取难题 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader …...

Puock主题的Gutenberg区块支持:现代化编辑体验终极指南

Puock主题的Gutenberg区块支持&#xff1a;现代化编辑体验终极指南 【免费下载链接】wordpress-theme-puock :art: 一款基于WordPress开发的高颜值的自适应主题&#xff0c;支持白天与黑夜模式/无刷新加载/第三方登录等众多功能 | A high-value adaptive theme based on WordPr…...

WarcraftHelper:魔兽争霸3终极兼容性工具,轻松实现5大版本完美适配

WarcraftHelper&#xff1a;魔兽争霸3终极兼容性工具&#xff0c;轻松实现5大版本完美适配 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 你是否想让…...