期末考考完了,花了一下午把之前一直悬而未决的一个小项目富文本坑填上了,真的是心酸。
其实富文本本来就是个坑,前后端分离之后的富文本更加是个坑了。
不多说,先是参考的代码网址
https://www.cnblogs.com/ocean-sky/p/7132319.html?tdsourcetag=s_pctim_aiomsg
说一下里面大牛的主要思路,主要就是把原先的JSP实现强行拆分,把jar包和配置文件写到后台,静态资源放到前端。
首先是配置
很简单,就是有个config.json文件,我们可以把它放在后台目录resources下面,如图所示,
然后去把里面json格式的数据变成HashMap,当然你也可以直接写成HashMap或者Java类,这样可以跳过下面说的第一个坑。
第一个坑 打包后的资源文件读取问题
打成jar包后的Springboot项目无法从resource里面读取文件,有经验的人肯定不会碰到了,我第一次碰到,我一开始是用classpath+相对路径去读文件,本地运行一切正常很完美,然后部署到Linux服务器上就出现了问题。这个文件是找不到,也就是不存在的。
网上看了很多,基本上锁定了Resource的工具类,用Resource将资源取出然后getFile,这个时候又出现了新的问题,File依然读不到,然后又去找了很多,去StackOverflow上找到了解决思路:
Springboot的资源文件不支持直接File整体得到,但是可以直接获取文件的InputStream,下面是代码:
Resource resource=new ClassPathResource("config.json");
String configContent=this.readFile(resource.getInputStream());
try {
JSONObject jsonConfig = new JSONObject(configContent);
this.jsonConfig = jsonConfig;
} catch (Exception e) {
this.jsonConfig = null;
}
然后是上传文件:
大牛其实已经写的差不多了,接下来就是很简单的操作了,在Todo后面把文件上传代码补全就好了,这里要注意写自己的逻辑,config.json那里的路径对应改成自己的,大牛是用FTP方式上传的,我们其实很简单用Files.copy就好了,直接用流操作更简单不是吗。
当然用流注意把前面的二进制注释掉,不然流会被刷空的。
下面是我的逻辑
Files.copy(is, Paths.get("/www/Image/"+picName));
boolean success = true;
//如果上传成功
if (success) {
state = new BaseState(true);
state.putInfo("size", tmpFile.length());
state.putInfo("title", picName);//文件名填入此处
state.putInfo("group", "");//所属group填入此处
state.putInfo("url", picName);//文件访问的url填入此处
tmpFile.delete();
} else {
state = new BaseState(false, 4);
tmpFile.delete();
}
return state;
我这里是存到服务器上的/www/Image/文件夹下,然后这里返回的url是对富文本访问的图片路径返回,这里直接用网络地址返回,当然有种很简单的方法,是你有个OSS文件服务器,那就没什么毛病了。
如果你和我一样是存到一台服务器而且前后端分离使用nginx反向代理部署,那就要注意下面一个坑:
第二个坑:如何配置nginx静态代理图片资源
前端端口是A,后台端口是B
下面是我的方法:
一开始是直接代理在前端端口A,
代理方法如下:
然后就出现了问题,这样代理之后图片固然是上传了,能显示了,而会出现前端的其他静态资源无法访问了,那些富文本的图标访问不到了的。
这也不难理解,因为你前面多了层nginx的查询,之代理了那个文件夹下的所有图片。
我的解决方法是再另开一个端口C,nginx监听这个端口,把静态资源代理到这个端口下去
然后返回体里的对应前缀改成端口C就可以了。
图片上传的问题就解决了。
最后是数学公式的问题
大牛写的里面是没有数学公式的,而我正好有这个需求,其实很简单,主要方法就是在前端改,加个下面公式的插件
具体可以百度,然后公式的上传有很多选择,一种是Latex直接上传,一种是变成图片上传,Latex就比较简单,因为就是富文本的一个整体,直接当成字符串和H5的代码一起上传就没什么毛病了,还有是图片,其实和上面的逻辑一样,把前端的Action代码改成和上传图片的Action一致应该就可以了。
接下来是富文本显示的问题:别的没什么好讲,就是把H5渲染出来,用V-HTML搞定一切。
最后一坑: Latex数学公式在Vue显示的问题
你会发现在Vue里,用了MathJax你用Latex公式编辑出来的公式仍然还是Latex,原因是MathJax解析的时候相当于在原有的页面动态添加元素,而V-html不会去渲染原先页面没有的元素,也不会有原先页面没有的CSS属性,解决方法其实官网已经有了:
getContent: function(){
this.content = this.$refs.ueditor.getUEContent();
this.$nextTick(function () {
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
})
},
用nextTick函数,把要动态操作元素的操作放在nextTick那里去。
就可以加载出数学公式了。
文件什么的和图片上传是类似的,没什么好讲。
综上就完成了富文本所有的内容。