IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> springboot集成editor.md进行markdown文档的编写及查看 -> 正文阅读

[Java知识库]springboot集成editor.md进行markdown文档的编写及查看


一、Editor.md简介

Editor.md 是一款开源的、可嵌入的 Markdown 在线编辑器(组件),基于 CodeMirror、jQuery 和 Marked 构建

二、与springboot集成过程

本文为springboot与editor.md的集成例子,详细说明如何在springboot工程中使用editor.md进行markdown文档的编写,包含前端页面与后台数据库及接口,例子很完整,建好库表后,启动工程即可测试。

2.1springboot后台部分的准备

2.1.1 数据库建表

建立一张文章表用来存储markdown文章:

DROP TABLE IF EXISTS `article`;
CREATE TABLE `article`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `title` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文章名称',
  `content` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '文章md的内容',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

2.1.2 springboot添加mybatis

略,可详参考本文最后的源码里面查看

2.1.3 springboot对article表进行增删改查

public interface ArticleService {
	//查看所有文章列表
	public List<Article> getArticleList();
    //添加文章
    public int addArticle(Article article);
    //更新文章
    public int updateArticle(Article article);
    //删除文章
    public int deleteArticle(Article article);
    //根据文章id查询文章
    public Article getArticleById(Integer id);
}

另外ArticleController类中增加一个文件上传接口用来进行图片的上传,上传至临时目录
还有两个查看图片的接口(查看临时目录下的图片,和查看正式目录下的图片)

	//临时照片展示
    @GetMapping("/getTempImage")
	
	//正式照片展示,md上传的新照片,是先以/getTempImage?fileName=xxx的方式临时存放
    //发表文章或修改文章时,通过以文章Id为目录将文章的图片独立出去管理,
    //正式的照片访问url如:/getImage?id=10&fileName=xxxxxxxxxxxx.jpg
    @GetMapping("/getImage")
     
     //上传图片并回显
    @ResponseBody
    @RequestMapping("/article/uploadImg")

注:
md上传的新照片,是先以/getTempImage?fileName=xxx的方式临时存放,等发表文章或修改文章时,通过以文章Id为目录将文章的图片独立出去管理,l如:/getImage?id=10&fileName=xxxxxxxxxxxx.jpg,此逻辑在ArticleServiceImpl类的addArticle和updateArticle方法中都有相应的实现代码,如:

	@Override
	@Transactional
	public int addArticle(Article article) {
		
		try {
			//先插入数据库
			articleMapper.addArticle(article);
			
			//取出自增id
			int id = article.getId();
			
			//将文章内容中的临时图片转换成正式的图片访问地址
			String articleContentTemp = article.getContent();
			
			//重新更新进去,articleContent.replaceAll后不会改变articleContent的值,在后面会继续进行临时图片的查询并替换
			article.setContent(article.getContent().replaceAll("/getTempImage\\?fileName=", "/getImage\\?id="+id+"&fileName="));
			articleMapper.updateArticle(article);
			
			//============================
			//查找文章内容中临时的图片,在文章保存(新增或修改)到数据库时,同时将临时目录下的图片迁移到以文章Id为目录的图片文件夹
			String tempImagePattern = "(getTempImage\\?fileName=)(\\w+-\\w+-\\w+-\\w+-\\w+\\.\\w+)(.*)";
			Pattern r = Pattern.compile(tempImagePattern);
			Matcher m = r.matcher(articleContentTemp);

			boolean imageDirCreted = false;
			while(m.find()){
				
				if(!imageDirCreted){
					Path newRealPath = Paths.get(imageAbsoluteFilePath+"/"+imageUploadPathPrex+"/"+id);
					//创建文件夹(不存在则创建)
					Files.createDirectories(newRealPath);		
					imageDirCreted = true;
				}
				
				String tempImageFileName = m.group(2);
			    try {
			    	Path fileRealPath = Paths.get(imageAbsoluteFilePath+"/" + imageUploadPathPrex + "/" + tempPrex + "/"+tempImageFileName);
			        Path newRealPathOfFile = Paths.get(imageAbsoluteFilePath+"/" + imageUploadPathPrex + "/"+id+"/"+tempImageFileName);
			        //覆盖式地复制文件
			        //Files.copy(fileRealPath, newRealPathOfFile, StandardCopyOption.REPLACE_EXISTING);
			        
			        //将临时图片移至正式目录(以文章id命名的目录)
			        logger.info("将临时图片移至正式目录,{},fileName:{}",id,tempImageFileName);
			        Files.move(fileRealPath, newRealPathOfFile);
			        
			        
			    } catch (IOException e) {
			        throw new RuntimeException("重命名文件失败");
			    }
			    
			}
			
			//最后,比对正式目录下的所有图片,将一些垃极图片从正式目录中也删除
			String tempImagePattern2 = "(getImage\\?id=\\d+&fileName=)(\\w+-\\w+-\\w+-\\w+-\\w+\\.\\w+)(.*)";
			Pattern r2 = Pattern.compile(tempImagePattern2);
			Matcher m2 = r2.matcher(article.getContent());
			HashSet<String> imageFileNameSet = new HashSet<String>();
			while(m2.find()){
				imageFileNameSet.add(m2.group(2));
			}
			File dir = new File(imageAbsoluteFilePath+"/"+imageUploadPathPrex+"/"+id);
			if(dir.exists()){
				String[] fileNames = dir.list();
				List<String> needDeleteFiles = new ArrayList<String>();
				for(String fileName : fileNames) {
					if(!imageFileNameSet.contains(fileName)){
						needDeleteFiles.add(fileName);
					}
				}
				for(String needDeleteFileName : needDeleteFiles){
					File file = new File(dir, needDeleteFileName);
					//从正式目录删除无效文件
			        logger.info("从正式目录删除无效文件,{},fileName:{}",id,needDeleteFileName);
					boolean success = file.delete();
					if(!success){
						throw new RuntimeException("删除无效文件失败:"+ needDeleteFileName);
					}
				}				
			}
			
			
		} catch (Exception e) {
			logger.error("error",e);
			throw new RuntimeException(e.getMessage());
			
		} finally {
			
		}
		
		return article.getId();
	}

2.2editor.md搭建过程

2.2.1editor.md下载

官网地址:https://pandao.github.io/editor.md/en.html
或我的网盘分享:

链接:https://pan.baidu.com/s/1Dl62ld1u6p5Z8ZNTijWhxA
提取码:2zan

2.2.2editor.md资源文件准备

在springboot工程中新建static文件目录(如果没有的话)然后将下载压缩包中的相应文件复制进去。
在这里插入图片描述
另外editormd.js相关的我新建了一个新的js目录来存放,
在这里插入图片描述

2.2.3编写相关前端页面

这里我写了三个页面articleList.html(文章列表)previewArticle.html(文章查看)showEditor.html(markdown编辑)

编辑器的构造代码如:

testEditor = editormd("test-editormd", {
    width   : "100%",
    height  : 640,
    syncScrolling : "single",
    path    : contextPath + "/lib/",
    imageUpload: true, //同意图片上传
    imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
    imageUploadURL: contextPath +"/article/uploadImg",       //图片上传URL 即后台的图片上传接口URL
    onload : function() {
        
    }
});

在这里插入图片描述

浏览文章代码如:

var testEditormdView2 = editormd.markdownToHTML("test-editormd-view2", {
    htmlDecode      : "style,script,iframe",  // you can filter tags decode
    emoji           : true,
    taskList        : true,
    tex             : true,  // 默认不解析
    flowChart       : true,  // 默认不解析
    sequenceDiagram : true,  // 默认不解析
});

2.2.4界面测试效果

测试地址:http://localhost:8080/articleList.html

文章列表(没什么样式)
在这里插入图片描述
编辑文章或发表新文章
在这里插入图片描述
发布后浏览的示例效果如
在这里插入图片描述
动态图:
在这里插入图片描述

三、部分问题解决

3.1使用editormd时候katex.min.css加载超慢

由于他引用了国外的cdn导致加载变慢甚至不能加载的情况,我们需要修改到自己的服务器路径

http://micuer.com/static/js/katex.min.css
http://micuer.com/static/js/katex.min.js

下载好上述2个文件后,修改文件editormd.js大约4181行

    // 使用国外的CDN,加载速度有时会很慢,或者自定义URL
    // You can custom KaTeX load url.
    editormd.katexURL  = {
        css : "css/katex.min",
        js  : "js/katex.min"
    };

3.2Editor.md编辑器默认上传的图片太小不能控制解决

无法手动控制图片大小,默认是最大的,有时需要想自己设置大小比如 ![图片描述](url =300x150)

首先找到lib目录中的marked.min.js这个文件
然后定位Renderer.prototype.image 这个就是生成图片html的位置,原代码如:

Renderer.prototype.image = function(href, title, text) {
            var out = '<img src="' + href + '" alt="' + text + '"';
            if (title) {
                out += ' title="' + title + '"'
            }
            out += this.options.xhtml ? "/>" : ">";
            return out
        }

修改后:

Renderer.prototype.image = function(href, title, text) {
            var array = href.split("=");
            var width;
            var height;
            if(array.length == 2){
                href = array[0];
                var resolution = array[1].split("x");
                if (resolution.length == 2){
                    width = resolution[0]
                    height = resolution[1];
                }
            }
            var out = '<img src="' + href + '" alt="' + text + '"';
            if (title) {
                out += ' title="' + title + '"'
            }
            if(width){
                out += ' width="' + width + '"'
            }
            if(height){
                out += ' height="' + height + '"'
            }
            out += this.options.xhtml ? "/>" : ">";
            return out
        };

修改后,通过在线的Js压缩工具进行js压缩后,替换到marked.min.js即可

四、demo源码下载

github:   https://github.com/jxlhljh/springbootmarkdowndemotest.git
gitee:  https://gitee.com/jxlhljh/springbootmarkdowndemotest.git
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-31 23:49:43  更:2022-03-31 23:50:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:23:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码