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

[黑马头条]-基于MinIO存储文章详情

目录

文章详情

需求分析

实现方案

实现步骤


文章详情

需求分析

如图所示,就是将文章详情存储在MinIO中,这样下次请求的时候就会直接从MinIO中返回页面,降低请求对数据库的访问压力,提高系统的可用性。

实现方案

思路分析:

关于存储图文等文件,我们一般有三种方式:第一种是直接基于电脑的磁盘存储,这种方式开发便捷,成本低但是扩展比较困难;第二种方式是基于第三方存储,就比如阿里云,腾讯云等,这种方式开发简单,功能强大,并且免维护,但是这种第三方提高的服务一般都是收费的,所以本项目也没有采用;在本项目中,我们选择了更加容易实现扩容的分布式文件系统minIO,它非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。它具备数据保护,高性能,可扩容,SDK支持,有操作界面,功能简单,开箱即用,具有丰富的API等优点,使得它成为了目前企业实现分布式文件存储的首选。在本项目中,我们将MinIO下载在了docker平台上,下载镜像后直接创建容器,再与项目整合便可使用,为了简化minIO的开发,我们还封装MinIO为starter,定义了minIO的操作类,当其他模块需要使用minIO存储文件的时候,只需要导入模块依赖,便可以通过minIO操作类实现文件上传/下载等功能。在本项目中具体表现为,app端查看文章详情有两种方式,一种是用户根据文章的id去查询文章内容表,然后将查询的数据返回给前端页面渲染,这种方式每一次请求都需要查询数据库,会给数据库带来一定的访问压力,对于一些高并发的项目便有些捉襟见肘;另一种方式是在根据id查询文章内容表时,根据文章内容通过Freemarker模板引擎技术生成静态的html文件,再把这个文件存入分布式文件系统minIO中,这里需要把我们生成好的html文件的访问路径写入到文章表中;当下一次访问该文章详情展示时,请求会直接通过获取指定文章的html的url路径去minIO中访问静态页面,然后再展示给前端。基于这一种方式,在很大程度上提高了系统的访问速度和并发能力。

实现步骤

1.在artile微服务中添加MinIO和freemarker的支持,参考测试项目

2.资料中找到模板文件(article.ftl)拷贝到article微服务下

3.资料中找到index.js和index.css两个文件手动上传到MinIO中

在文章微服务中导入依赖

   <dependencies><!--导入freemarker模板的依赖,用来生成静态页面--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!-- 导入自己定义的heima-leadnews-basic下面的heima-file-starter,引入minio功能--><!--因为heima-file-starter有minio功能,所以可以通过依赖传递使得该模块也有minio功能--><dependency><groupId>com.heima</groupId><artifactId>heima-file-starter</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>

其中,freemarker的依赖是官方提供的;heima-file-starter是我们自定义的starter,导入依赖就可以使用我们的MinIO存储文件。

新建ApArticleContentMapper

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.heima.model.article.pojos.ApArticleContent;
import org.apache.ibatis.annotations.Mapper;
//文章内容接口访问层,集成了mp的BaseMapper接口,拥有对ApArticleContent基本的增删改查功能
@Mapper//表示当前是一个接口访问层
public interface ApArticleContentMapper extends BaseMapper<ApArticleContent> {
}

在artile微服务中新增测试类(后期新增文章的时候创建详情静态页,目前暂时手动生成)

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.article.ArticleApplication;
import com.heima.article.mapper.ApArticleContentMapper;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleContent;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;@SpringBootTest(classes = ArticleApplication.class)
@RunWith(SpringRunner.class)
public class ArticleFreemarkerTest {@Autowiredprivate Configuration configuration;@Autowiredprivate FileStorageService fileStorageService;@Autowiredprivate ApArticleMapper apArticleMapper;@Autowiredprivate ApArticleContentMapper apArticleContentMapper;@Testpublic void createStaticUrlTest() throws Exception {//1.获取文章内容ApArticleContent apArticleContent = apArticleContentMapper.selectOne(Wrappers.<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, 1390536764510310401L));if(apArticleContent != null && StringUtils.isNotBlank(apArticleContent.getContent())){//2.文章内容通过freemarker生成html文件StringWriter out = new StringWriter();Template template = configuration.getTemplate("article.ftl");Map<String, Object> params = new HashMap<>();params.put("content", JSONArray.parseArray(apArticleContent.getContent()));template.process(params, out);InputStream is = new ByteArrayInputStream(out.toString().getBytes());//3.把html文件上传到minio中String path = fileStorageService.uploadHtmlFile("", apArticleContent.getArticleId() + ".html", is);//4.修改ap_article表,保存static_url字段ApArticle article = new ApArticle();article.setId(apArticleContent.getArticleId());article.setStaticUrl(path);apArticleMapper.updateById(article);}}
}

这段代码是一个Spring Boot的测试类`ArticleFreemarkerTest`,它使用了Spring的测试支持和Freemarker模板引擎来生成静态HTML文件。测试类中注入了Freemarker的`Configuration`对象、文件存储服务`FileStorageService`、文章Mapper `ApArticleMapper`和文章内容Mapper `ApArticleContentMapper`。在`createStaticUrlTest`测试方法中,首先通过文章内容Mapper查询特定文章的内容,然后使用Freemarker模板`article.ftl`和查询到的内容生成HTML文件,接着调用文件存储服务将生成的HTML文件上传到MinIO对象存储中,并获取文件的访问路径,最后更新文章的静态URL到数据库中。这个过程展示了如何将动态内容转换为静态文件并存储,同时更新数据库记录以反映这一变化。

http://www.lryc.cn/news/593609.html

相关文章:

  • 代码随想录算法训练营第二十五天
  • Streamlit 官翻 3 - 开发教程 Develop Tutorials
  • 80、【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈空间对齐
  • Input输入和Screen相关
  • 轻松学习C++:基本语法解析
  • 从丢包到恢复:TCP重传机制的底层逻辑全解
  • 将HTML+JS+CSS数独游戏包装为安卓App
  • 微服务学习(六)之分布式事务
  • 华为擎云L420安装LocalSend
  • Java大视界:Java大数据在智能医疗电子健康档案数据挖掘与健康服务创新>
  • kafka--基础知识点--6.1--LEO、HW、LW
  • LeetCode Hot100【7. 整数反转】
  • 创意 C++ 文本冒险战斗游戏代码
  • Uniapp之自定义图片预览
  • 下一场范式革命:Transformer架构≠最终解法
  • Spring IOC容器在Web环境中是如何启动的(源码级剖析)?
  • Java多线程进阶
  • Node.js net.Socket.destroy()深入解析
  • [spring6: AspectMetadata AspectInstanceFactory]-源码解析
  • 零基础学习性能测试第二章-监控体系
  • OllyDbg技巧学习
  • Redis 如何保证高并发与高可用
  • Python爬虫实战:研究pefile库相关技术
  • PCB 混合介质叠层:材料特性匹配与性能提升的技术解析
  • 1. Spring AI概述
  • OSPF高级特性之Overflow
  • 【c++】提升用户体验:问答系统的交互优化实践——关于我用AI编写了一个聊天机器人……(12)
  • Buildroot vs Yocto:SDK 构建机制的核心差异与实践案例
  • 多线程 示例
  • QT窗口(8)-QFileDiag