通过页面静态化实现预览功能(GridFS的使用)

一. 静态化流程

模型数据 + 页面模板 => 页面静态化 => 预览

不同页面的数据模型不同,为其设置一个dataUrl用于请求模型数据,
使用远程调用RestTemplate请求dataUrl获取到模型数据。

获取页面模板,模板文件统一管理并存储在分布式文件存储系统GridFS中。

执行页面静态化,渲染页面。

二. GridFS

2.1 基本概念

MongoDB提供的分布式文件存储系统。

分块存储,按照256KB的大小分割。
chunks存储文件的二进制数据,files存储文件的元数据信息(文件名,块大小,上传时间等)。

读取文件会将块进行组装合并,因此效率并不是很高。

fs.chunks
在这里插入图片描述
fs.files
在这里插入图片描述

2.2 代码实现

通过调用GridFsTemplate的store方法存储,并且返回一个文件id。
会将文件的基本信息存储在fs.files中(文件id作为主键),而通过files_id关联到fs.chunks,文件的二进制数据就存储在其中。

上传文件:

    @Autowired
    private GridFsTemplate gridFsTemplate;
   
    @Test
    public void storeToGridFs() {
        // 需要存储的文件
        File file = new File("E:\\workspace\\index_banner.ftl");
        ObjectId objectId = null;
        try {
            objectId = gridFsTemplate.store(new FileInputStream(file), "banner_test.ftl");
            log.info("【上传文件至GirdFS】, 文件id = {}", objectId);
        } catch (FileNotFoundException e) {
            log.error("【上传文件至GirdFS有误】 : {}", e);
        }
    }

返回的文件id:
在这里插入图片描述
fs.files:
在这里插入图片描述
fs.chunks:
在这里插入图片描述

读取文件:

需要GridFSBucket打开下载流,
GridFSBucket需要装配到Spring容器中。

@Configuration
public class MongoConfig {

    @Value("${spring.data.mongodb.database}")
    private String mongoDB;

    @Bean
    public GridFSBucket getGridFSBucket(MongoClient mongoClient) {
        MongoDatabase database = mongoClient.getDatabase(mongoDB);
        GridFSBucket gridFSBucket = GridFSBuckets.create(database);
        return gridFSBucket;
    }
}

下载文件:

    @Autowired
    private GridFSBucket gridFSBucket;
    
    @Test
    public void downloadFromGridFS() {
        // 从gridfs中获取文件
        // 1. 根据文件id查询文件
        GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is("5c4ac26c8d7e7524b4526852")));
        // 2. 打开下载流对象, 需要指定文件id
        GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
        // 3. 创建gridfsResource对象,获取流
        GridFsResource gridFsResource = new GridFsResource(gridFSFile, gridFSDownloadStream);
        // 4. 从流中获取数据
        try {
            String data = IOUtils.toString(gridFsResource.getInputStream(), "utf-8");
            log.info("【从GridFS获取文件】: {}", data);
        } catch (IOException e) {
            log.error("【从GridFS获取文件有误】: ", e);
        }
    }

即可获取文件内容:
在这里插入图片描述

三. 页面静态化

(获取页面数据与模板代码略,通过restTemplate请求dataUrl获取模型数据,模板文件从GridFS下载)

	 /**
     * 页面静态化
     * @param templateContent 模板
     * @param model 模型数据
     * @return
     */
    private String generateHtml(String templateContent, Map model) {
        // 1. 获取配置对象
        Configuration configuration = new Configuration(Configuration.getVersion());
        // 2. 获取模板加载器, 可使字符串变为模板文件
        StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
        stringTemplateLoader.putTemplate("template", templateContent);
        // 3. 向configuration配置模板加载器
        configuration.setTemplateLoader(stringTemplateLoader);
        try {
     		// 4. 获取模板
            Template template = configuration.getTemplate("template");
            // 5. 执行静态化页面
            String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
            return html;
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
            return null;
        }
    }

执行静态化后通过HttpServletResponse写出。

四. 页面动静结合的情况

4.1 方案

动态内容较少的情况下:
静态化生成html页面放在Nginx中。
浏览器可通过Nginx访问到页面。
而页面中的动态数据会通过Ajax请求服务端。

4.2 静态页面分析

分析页面的静态信息与动态信息。
通过SSI拆分成多个页面,通过Nginx再合并。

静态资源,将页面通过SSI技术分割成几块:页头、页尾、根据具体业务分割的其它页面等。

滞后显示(统计信息)的数据可异步加载,静态化成json。

实时显示的数据是完全动态的,引入动态js脚本,用来获取数据。

4.3 配置静态资源虚拟主机(跨域)

配置Nginx的配置文件:静态资源的代理路径等。

cors跨域参数:

location /static/plugins/ {
alias E:/xxxx
add_header Access-Control-Allow-Origin http://xxxx.com;:允许跨域访问的外域地址。
add_header Access-Control-Allow-Credentials true;:允许客户端携带证书访问。
add_header Access-Control-Allow-Methods GET;:允许客户端跨域访问的方法。
}

4.4 页面预览实现步骤
  1. 页面数据模型查询接口。

  2. 页面模板(freemarker、thymeleaf)

  3. 模板文件统一管理,模板信息存储至模板表中,而模板文件存储至GridFS(返回一个文件id,将文件id作为字段存储在模板表中)。

  4. 返回前端页面预览的url。(需要页面id,新增/更新页面返回页面id,拼接页面预览url)

  5. 访问页面预览的url调用页面静态化接口。

    需要html页面才可解析SSI标签,因此需要设置响应头:response.setHeader("Content-type", "text/html;charset=utf-8");

其中getPageHtml()方法中有三步骤,上文有提起,就是获取模型数据与页面模板,然后执行页面静态化,就是上文的generateHtml()

	 /**
     * 页面预览
     * @param pageId
     * @throws IOException
     */
    @GetMapping("/{pageId}")
    public void previewPage(@PathVariable("pageId") String pageId) throws IOException {
        // 页面静态化
        String pageHtml = pageService.getPageHtml(pageId);
        // response向浏览器输出
        ServletOutputStream outputStream = response.getOutputStream();
        // 设置html响应头用于SSI解析
        response.setHeader("Content-type", "text/html;charset=utf-8");
        outputStream.write(pageHtml.getBytes("utf-8"));
    }

(这里的response就是HttpServletResponse,因为继承了一个BaseController,里面有HttpServletRequest、HttpServletResponse、HttpSession)

五. 总结

当操作人员点击页面预览时,会访问一个页面预览url,该url后面拼接的是页面的id。

该地址会请求页面预览的接口,即执行页面静态化。

页面静态化前需要编写页面模板,编写获取页面数据模型的接口。
模板+数据模型=>静态化页面

而预览页面的时候一般都还未存储过该页面,无法得到页面id,所以需要新增页面(多次预览即更新页面)返回一个页面id,再根据静态化接口的请求映射路径拼接成预览url。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值