一般情况下,文章类的内容我们存放到数据库时,是以Blob类型存储,因为文章中可能含有图片、附件、音频、或者小视频等。而在从数据库读取blob内容后需要转换成string返给前端展示。近期做了一个文章管理类的功能,现在把用到的相关技术知识点总结下,以便以后用到时查阅,也希望给一些其他小伙伴一些帮助。
一、添加文章
添加文章也就是把前端传给后台的文章内容存到数据库里。这里只说如何把string转成blob
一般情况,前端是把文章的html格式传给后台,因为文章的内容包含了各种格式,比如加粗、字体大小、字体颜色等。这个转成html格式的文章内容是有前端来实现的。
一般文章内容字段我们设置成byte[]数组类型。然后把byte数组类型的文章内容直接存到数据库的Blob字段。那么文章内容是string转byte数组也比较容易了,这里指定了编码格式
byte[] actricleContent = contentStr.getBytes("UTF-8");
二、读取文章内容
从数据库查询到记录,可以直接转换为Blob,我这里用的mybatis-plus,返回的是map,我采用的直接强转。
List<Map> mapList = articleService.qryArtilceById(articleId);
Map article = mapList.get(0);
Blob blob = (Blob)article.get("content");//Blob是java.sql包下
还需把blob转成string,但是blob不能直接转string,blob可以转byte[]。具体如下:
public byte[] blobToByte(Blob blob) throws Exception {
byte[] bytes = null;
try {
InputStream in=blob.getBinaryStream();
BufferedInputStream inBuffered = new BufferedInputStream(in);
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
byte[] temp = new byte[1024];
int size = 0;
while ((size = inBuffered.read(temp)) != -1) {
out.write(temp, 0, size);
}
inBuffered.close();
in.close();
bytes = out.toByteArray();
} catch(Exception ex){
ex.printStackTrace();
}
return bytes;
}
然后转string返给前端:
Stirng content = new String(blobToBytes(blob),"UTF-8");
其实到这里实现了文章的存储和读取过程,但是有时候我们只返给前端文章的前200字,并把文章的第一张图片返给前端来展示。有时候会有这样的需求。这时候返给前端的文章前200字就需要把html标签去掉,并且把图片、附件等去掉,因为只展示文字嘛,且是不带任何格式的文字。至于如何去掉文章中的html标签等,我另一篇blog写了,请参考:https://blog.csdn.net/dhklsl/article/details/115620016?spm=1001.2014.3001.5501
我把代码也拿过来了,建议去看那篇blog,前因后果都讲清了。
//content是文章内容的html
//static/tinymce4.7.5/plugins/img/01.gif 是表情符路径,所有表情符号前面路径都一样,
//只有名字不一样
//正则:(?!<(img|IMG) src=\"static/tinymce4.7.5/plugins/img/.*?/>)<.*?>
content = content.replaceAll("(?!<(img|IMG) src=\"static/tinymce4.7.5/plugins/img/.*?/>)<.*?>","");
//content = content.replaceAll("</?[^>]+]","");//这是去html所有标签
//过滤tab符号、回车、换行html
content = content.replaceAll("\t|\n|\r","");
//双引号替换为“”
content = content.replaceAll("“","\"");
content = content.replaceAll("”","\"");
//空格去掉
content = content.replaceAll(" ","");
if(content.length()>300){
content = content.substring(0,300);
}
System.out.printf("content=" + content);
上面的代码中第一行代码是去掉所有html标签,但是有一种特殊的img标签不去掉,原因是我们前端编辑器里表情符号不能去掉要展示出来。但是这个文本编辑器tinymce把自带的表情符转成了img,只是src属性的路径有一定的规律。所以这行代码就是去掉所有html标签但是对于特殊路径的img标签不去掉
另外一篇blog写了如何从文章内容中获取img标签的src以及a标签的href内容等。https://blog.csdn.net/dhklsl/article/details/115477936?spm=1001.2014.3001.5501
三、关于文章中图片及附件
我们项目中是有一个表,存储的是文章的id和文章包含的附件的对应关系。这样的设计增加了代码复杂度。一会我简单说下什么情况下增加了代码复杂度。
我先说下,那种方式比较简单,就是不要设计上面说的这张表,存储文章和附件间关系。前端在操作上传附件时,直接把附件【图片,文档】上传到服务器指定位置,前端给后台的是是包含html的文章内容,里面包含直接可以访问图片和附件的链接。
我们这种方式增加的复杂问题是:
一是用户开始添加了5张图片,还没有点保存时,用户直接从文本编辑器删除了2张图片,再点保存。但是这张表里存了5张图片,保存文章内容后,还有修改表里五张图片的对应的文章id【因为添加图片时文章id还没生成】。但是真正是文章关联了3张图片而不是5张。前端有没法判断用户删除了那2张。这就很麻烦,需要从文章里读取所有图片的src,里面有图片的id,然后根据图片id更新表里的文章id。
二是修改文章时也存在这个问题。比如用户删除了其中一张图片点保存。就需要再次更新这张表,那是一个麻烦。