在Java项目中,做内容管理功能时,需要用到富文本编辑器,目前流行的富文本编辑器还是比较多的,因为项目中用的是百度的UEditor,所以对UEditor使用中的一些问题做个总结吧。
因为是Java项目所以使用的是只能选择jsp版本的UEditor,使用方式还是比较简单的,按照UEditor官方的文档来就好了。
首先说下踩过的坑,我项目一开始是用的war部署的方式,大家都知道war部署时是会解压到tomcat的webapps目录的,这样是可以通过系统地址访问到这个controller.jsp文件的(UEditor的前端js中配置的上传地址就是host:port/controller.jsp?action=upload,需要直接访问该文件),但将项目打包成jar包运行后,使用同样的配置,是无法访问到该文件的,因为它是被打包在jar包里面的,通过host:port/controller.jsp是无法访问的,因此如果你的项目是jar部署的,这个controller.jsp是必须要干掉的,不然是无法实现上传功能的。
还有一个坑,项目打包方式改成jar包后,将controller.jsp改造后,想着现在应该能上传了吧,但现实总是很骨感,一直返回配置不正确,经过打断点跟踪调试,发现是初始化配置文件的时候出错了,UEditor源码目录有个config.json文件,一般我们会把config.json文件放到项目的resources目录,该文件存放了各种要上传的文件类型的配置,先看下加载该配置文件的源码实现
private void initEnv () throws FileNotFoundException, IOException {
File file = new File( this.originalPath );
if ( !file.isAbsolute() ) {
file = new File( file.getAbsolutePath() );
}
this.parentPath = file.getParent();
String configContent = this.readFile( this.getConfigPath() );
try{
JSONObject jsonConfig = new JSONObject( configContent );
this.jsonConfig = jsonConfig;
} catch ( Exception e ) {
this.jsonConfig = null;
}
}
private String getConfigPath () {
String path = this.getClass().getResource("/").getPath() + ConfigManager.configFileName;
if (new File(path).exists()) {
return path;
}else {
return this.parentPath + File.separator + ConfigManager.configFileName;
}
}
分析源码可以看到,读取config.json文件的方式都是通过文件的操作来完成的,这种方式在war部署时是没有问题的,因为可以获取到文件的绝对路径,然后读取文件,但是通过jar部署,是将文件打包在jar包的,是不会解压开来的,因此通过文件操作的方式是无法读取到config.json文件的,所以在加载配置文件的时候出错了。
首先改造的是UEditor中的controller.jsp文件。先吐槽一下,如果放在几年前,使用jsp文件来写前端还比较流行的时候,引入jsp版的UEditor,不会觉得有什么不妥,但是在现在前端框架百花齐放的年代,angularJS、React、Vue等等各种前端框架琳琅满目,基本上已经见不到jsp页面文件的影子了,同时前后端代码完全分离的代码管理模式下,此时引入一个jsp版的UEditor,在Java代码的resource目录下突然多了个jsp文件,总感觉很膈应,暂不知道为啥UEditor要放个jsp文件在项目里。
吐槽完毕,进入正题。
先分析下controller.jsp这个文件的作用,贴上源码
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="com.baidu.ueditor.ActionEnter"
pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%
request.setCharacterEncoding( "utf-8" );
response.setHeader("Content-Type" , "text/html");
String rootPath = application.getRealPath( "/" );
out.write( new ActionEnter( request, rootPath ).exec() );
%>
代码很简单,就是做了个响应头的设置,然后将ActionEnter类中的exec方法执行结果返回给浏览器。
如果看过ActionEnter类的源码就知道,就是做了个文件上传功能的事,具体代码这里就不分析了,有兴趣的同学可以去看看。
那么这个controller.jsp文件如何整改呢?最简单的方式就是servlet,了解java web基础的同学都知道,jsp的本质就是个servlet,在web容器中会将jsp转换成servlet,也就是个java类,这样就可以将这个看着扎眼的controller.jsp文件从项目中移除了。因为项目采用的是spring-boot框架,因此改造很简单,新建个类,加上@WebServlet注解就好了,不要忘了加上servlet的url pattern,然后将controller.jsp的java代码放到servlet中,最后将UEditor中的js文件的上传地址改成servlet的访问地址就完成了。
然后改造config.json文件的加载代码,google的guava包中提供了很多的工具类,其中就有对resource资源操作的类,Resources类中就提供获取resource目录文件内容的方法,直接静态方法调用就好了:
Resources.toString(Resources.getResource(this.configFileName),"utf-8")
就可以直接获取到config.json的内容了
经过测试完美的解决了问题(毕竟google出品)。