spring boot 渲染md格式模板

文章目录

写在前面

主要技术点:使用 thymeleaf+flexmark 渲染模板渲染 markdown 文件 ,highlight 渲染代码高亮 thymeleaf 模板负责渲染页面 flexmark 是 java 语言编写,负责将数据库中的 markdown 语法文本转为 html 文本 highlight 负责渲染 code 部分的代码,是一款 js+css 库

步骤

首先定义一个 controller 和 requstmapping

 1package com.kikt.web.ctl.blog;
 2
 3import com.kikt.service.markdown.MarkdownService;
 4import com.sun.org.apache.xpath.internal.operations.Mod;
 5import org.springframework.beans.factory.annotation.Autowired;
 6import org.springframework.stereotype.Controller;
 7import org.springframework.ui.Model;
 8import org.springframework.web.bind.annotation.RequestMapping;
 9import org.springframework.web.bind.annotation.RequestMethod;
10import org.springframework.web.bind.annotation.RequestParam;
11import org.springframework.web.bind.annotation.RequestPart;
12
13/**
14 * Created by cai on 2017/8/25.
15 */
16@Controller
17@RequestMapping("/md")
18public class MarkdownCtl {
19
20    @Autowired
21    private MarkdownService service;
22
23    @RequestMapping(value = "/parse", method = RequestMethod.POST)
24    public String parseMarkDown(Model model, @RequestParam("md") String markdownText) {
25        model.addAttribute("md", service.parseMarkdownString(markdownText));
26        return "test";
27    }
28
29    @RequestMapping(value = "/index", method = RequestMethod.GET)
30    public String index(Model model) {
31        model.addAttribute("inputName", "md");
32        return "markdown";
33    }
34
35}

在 static/templates 下定义一个文件,markdown.html

这样当访问 http://localhost:8080/md/index的时候,就会跳转到index页面中

 1<!DOCTYPE html>
 2<html
 3  xmlns:th="http://www.thymeleaf.org"
 4  xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"
 5>
 6  <head>
 7    <meta charset="UTF-8" />
 8    <script type="text/javascript" th:src="@{/js/jquery-3.2.1.min.js}"></script>
 9    <script type="text/javascript">
10      $(document).ready({});
11    </script>
12    <meta charset="UTF-8" />
13    <title>Title</title>
14  </head>
15  <body>
16    <form method="post" action="./parse">
17      <div>
18        <textarea
19          th:name="${inputName}"
20          title="md"
21          th:width="200px"
22          th:height="300px"
23        />
24        <button type="submit">提交</button>
25      </div>
26    </form>
27  </body>
28</html>

其中很简单,就定义了一个表单,表单中有一个输入框和一个提交按钮,这里模拟的是一个 post 提交表单的过程,提交的 url 为/parse 也就是/md/parse,对应的就是指向 test.html

 1<!DOCTYPE html>
 2<html
 3  xmlns:th="http://www.thymeleaf.org"
 4  xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"
 5>
 6  <head>
 7    <meta name="viewport" content="width=device-width,initial-scale=1" />
 8    <meta charset="UTF-8" />
 9    <link rel="stylesheet" th:href="@{/highlight/styles/default.css}" />
10    <script th:src="@{/highlight/highlight.pack.js}"></script>
11    <link rel="stylesheet" type="text/css" th:href="@{/css/markdown.css}" />
12    <script type="text/javascript" th:src="@{/js/jquery-3.2.1.min.js}"></script>
13    <script th:inline="javascript" type="text/javascript">
14      $(document).ready(function () {
15          var a = [[${md}]]
16          $("#div").html(a)
17          $('pre code').each(function(i, block) {
18              hljs.highlightBlock(block);
19          });
20      })
21    </script>
22    <title>Title</title>
23  </head>
24  <body>
25    <div id="div"></div>
26  </body>
27</html>

再来看下 js 中的代码是在后台定义的 attr,名字为 md,来源是 service service 的代码如下:

 1package com.kikt.service.markdown
 2
 3import com.kikt.ext.logger
 4import com.vladsch.flexmark.html.HtmlRenderer
 5import com.vladsch.flexmark.parser.Parser
 6import com.vladsch.flexmark.util.options.MutableDataSet
 7import org.springframework.stereotype.Service
 8
 9/**
10 * Created by cai on 2017/8/25.
11 */
12@Service
13open class MarkdownService {
14
15    fun parseMarkdownString(markdown: String): String {
16        val options = MutableDataSet()
17        val parser = Parser.builder(options).build()
18        val renderer = HtmlRenderer.builder(options).build()
19        val document = parser.parse(markdown)
20        val html = renderer.render(document)
21        logger.info("parse html = $html")
22        return html
23    }
24
25}

就是定义一个了第三方的 markdown 解析器,传入前端页面,再由前端页面通过 js 进行渲染 markdown.css 是我自己定义的一些渲染规则

 1blockquote {
 2  font: 18px normal helvetica, sans-serif;
 3  margin-top: 10px;
 4  margin-bottom: 10px;
 5  margin-left: 10px;
 6  padding-left: 8px;
 7  border-left: 9px solid #ccc;
 8}
 9
10pre {
11  font: 14px normal helvetica, sans-serif;
12  background-color: #efefef;
13  color: #333333;
14  margin-left: 5px;
15  padding: 10px;
16  margin-right: 30px;
17}
18
19a {
20  font: 16px normal helvetica, sans-serif;
21}
22
23blockquote p {
24  font-size: 18px;
25  margin-left: 0px;
26}
27
28p {
29  font-size: 14px;
30  margin-left: 10px;
31}
32
33p code {
34  background-color: #ededef;
35}

第三方库来源及用途

模板 用于渲染 java 中的视图层 java 中的库,用于转化 markdown 语法到 html 语法 java 的轻应用构建框架 高亮 pre 中的 code 语法 前端都知道的 js 框架

截图


屏幕快照 2017-08-27 下午3.58.02.png

屏幕快照 2017-08-27 下午3.58.09.png

后记

也没什么创新可言,主要就是做一个小技术点的总结

其实更节省资源的做法是将 markdown 从文本到 html 的语法全部交给前端解决,后端只负责储存,这样将解析的过程交给每个浏览器去解决是个更好的解决思路,这样的好处就是不论什么浏览器都可以正常的渲染出 markdown