UEditor无法上传图片
UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码。
首先,我先说一下我的项目情况,我的项目使用的是SSH框架,JDK版本是JDK1.6,是使用Tomcat服务器进行项目部署的。如果项目环境框架不同,这个教程也是可以详加参考的。
我现在需要在项目中加入Ueditor,首先富文本编辑器是出现了。
第一个问题是点击图片上传的按钮没有反应,js报错:“请求后台配置项http错误,上传功能将不能正常使用!”。
光是这个问题就看了很久,最后我进行了很多种操作,也不知道是哪个操作改好的,下面就总结一下。
1、查看配置文件是否配置正确
主要就是两个配置文件:
第一,ueditor -> ueditor.config.js
serverUrl修改为URL + "jsp/controller.jsp"
第二,ueditor -> jsp -> config.json
imageUrlPrefix改为你本地服务器的项目地址,如:http://192.168.10.2:8081/btc_dachang
2、查看controller.jsp是否能打开
首先找到自己的controller.jsp的路径,然后直接通过url打开这个jsp文件。
例:我的controller.jsp的路径为:/web/ueditor/jsp/controller.jsp
按照自己的项目路径修改后打开这个网址:http://192.168.10.2:8080/btc_dachang/ueditor/jsp/controller.jsp?action=config,如果返回了一串json,代表controller.jsp可以打开。如果无法打开,请查看问题五。
3、检查是否已导入jar包
Ueditor下的jsp文件夹下的lib文件夹中有5个jar包,必须全部关联到项目中,这里建议使用此处的jar包,如果和项目中有重复,替换掉项目中的冲突原jar包,原jar包直接删掉或者另存到本地其他文件夹,不要放在项目中,原因参考第五个问题。
4、使用其他版本的Ueditor
如果上面三个步骤都对且问题还没有解决的话,那可能是你项目中的Ueditor可能某个配置文件被改坏了,这个时候直接去下载一个最新的Ueditor,然后删掉项目中的原Ueditor,使用新下载的,重新导入并配置一遍。
第二个问题是java后台报错:Unable to find 'struts.multipart.saveDir' property setting.
这个问题比较好解决,直接在Struts.xml中加入这段代码即可:
第三个问题是后台报警告:org.apache.tomcat.util.http.Parameters processParameters WARNING: Parameters: Invalid chunk ignored.
这个问题可以不改,不会影响功能,出现这个警告的原因是因为传到后台的url中有&&这样的符号,在外部是看不出来的,只需要修改ueditor.all.min.js:
xhr.open(method, str, ajaxOpts.async);
--->
xhr.open(method, str.replace("&&","&"), ajaxOpts.async);
第四个问题是可以通过Ueditor上的上传图片按钮打开资源管理器了,但是选择图片并进行上传后,富文本编辑器中出现一个loading的圈圈,加载了一会就消失了,图片也不显示,甚至连叉都不显示。
这个问题我是通过问题一中的第四个步骤,也就是换了一个新的Ueditor版本修改好的,换成新的版本后,图片加载后会显示叉,不过也算解决了加载一会就完全消失的问题了。
第五个问题是图片上传后显示红叉,这是最严重的一个问题,也是算比较难的问题了。有些人可能浏览器控制台或服务器后台会提示未找到上传数据,也是这个问题。
这个问题其实分两种情况,第一种是过滤器将文件拦截掉了,第二种是jar包冲突了。
我给大家提供一下我找问题的方法,如果本篇文章不能帮助你解决问题的话,那么你自己也可以在本地慢慢找到问题的根源。这个方法就是后台debug。
去官网下载开发版的完整源码,然后将ueditor文件夹中jsp文件夹下的src文件夹下的com文件夹的拷贝出来,贴到自己的项目中,这里可以直接去javaworkspace下的项目文件夹中粘贴。然后将几个报错解决后就可以自己debug了。上传图片会走ActionEnter类中的invoke方法。最后会在StorageManager类的getTmpFile方法中报错:NoSuchMethodError: org.apache.commons.io.FileUtils.getTempDirectory()
定位到这之后就简单了,网上查了一下,原来是过滤器的原因,第一个问题中如果无法打开controller.jsp,也是因为过滤器拦截掉了请求。
我给大家提供两种方法:
第一种:重写过滤器
在我的项目中,一共有两个过滤器对controller.jsp进行了拦截,如下图:
那么我就需要重写两个过滤器,下面给大家展示一个,只需要把controller.jsp放出来就行了。如下图
代码:
public class UeditorStrutsFilter extends StrutsPrepareAndExecuteFilter {
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String url = request.getRequestURI();
System.out.println(url);
if (url.contains("jsp/controller.jsp")) {
chain.doFilter(req, res);
}else{
super.doFilter(req, res, chain);
}
}
}
这里你项目中有多少个把controller.jsp拦截掉的Struts过滤器,你就得重写多少个过滤器。一般来说是:StrutsPrepareAndExecuteFilter。我的项目中还有一个:StrutsPrepareFilter,其他字符拦截器之类的不用管。
过滤器重写完后,web.xml也是需要修改的,将重写的过滤器替换掉。
总结一下第一种方法,一共两个步骤。第一步,重写Struts过滤器,第二步,替换掉web.xml中重写的过滤器。
第二种:不进行拦截.jsp的请求
有些人可能觉得重写两个过滤器太烦了,那么我现在提供第二种简单的方法,不过这种方法虽然简单,但不如第一种方法严谨。
这种方法就是对jsp不进行拦截。具体方式就是在web.xml中的filter-mapping中不拦截所有请求,只拦截.do之类的请求。
<</span>filter>
<</span>filter-name>struts</</span>filter-name>
<</span>filter-class>interceptor.UeditorStrutsFilter</</span>filter-class>
<</span>init-param>
<</span>param-name>actionPackages</</span>param-name>
<</span>param-value>struts.xml</</span>param-value>
</</span>init-param>
</</span>filter>
<</span>filter-mapping>
<</span>filter-name>struts</</span>filter-name>
<</span>url-pattern>*.do</</span>url-pattern>
</</span>filter-mapping>
<</span>filter-mapping>
<</span>filter-name>struts</</span>filter-name>
<</span>url-pattern>*.action</</span>url-pattern>
</</span>filter-mapping>
<</span>filter-mapping>
<</span>filter-name>struts</</span>filter-name>
<</span>url-pattern>*.iframe</</span>url-pattern>
</</span>filter-mapping>
<</span>filter-mapping>
<</span>filter-name>struts</</span>filter-name>
<</span>url-pattern>*.so</</span>url-pattern>
</</span>filter-mapping>
<</span>filter-mapping>
<</span>filter-name>struts</</span>filter-name>
<</span>url-pattern>*.flow</</span>url-pattern>
</</span>filter-mapping>
<</span>filter-mapping>
<</span>filter-name>struts</</span>filter-name>
<</span>url-pattern>*.ajax</</span>url-pattern>
</</span>filter-mapping>
<</span>filter-mapping>
<</span>filter-name>struts</</span>filter-name>
<</span>url-pattern>*.jc</</span>url-pattern>
</</span>filter-mapping>
<</span>filter-mapping>
<</span>filter-name>struts</</span>filter-name>
<</span>url-pattern>*.js</</span>url-pattern>
</</span>filter-mapping>
将你的两个Struts过滤器对.jsp的请求不拦截。直接使用上面的filter-mapping就可以了,如果还有需要拦截的,也可以加。
总结一下第二种方法,修改web.xml,对.jsp请求不进行拦截。这种方式也可以解决这个问题,但不够严谨,可能会漏掉一些其他的请求。
前面描述的是过滤器将文件拦截掉的情况,在我个人的情况中,我的过滤器在改好后,居然还是报未找到上传数据的问题。那么原因是什么呢?
经过长时间的排除错误后,我发现由于我是用Tomcat来进行部署项目的,而且我是在apache-tomcat-6.0.20\conf\Catalina\localhost文件夹中新建xml的方式来进行项目部署的,那么这个时候的项目包其实就是引用的javaworkspace中项目下的web文件夹。
Tomcat部署方式可以参考:http://blog.sina.com.cn/s/blog_13887bf130102xcwo.html
所以虽然我MyEclipse中Build Path是引入的ueditor中的新jar包,但是老的jar包并没有删掉,所以在这个项目包文件夹中,依然是存在新版本的jar包和老版本的jar包的,也就造成了jar包冲突。
果然,在我将老jar包删掉后,重新运行服务器,图片上传功能就成功的可以使用啦!
总结一下,这个未找到上传数据的问题其实根本原因就是被过滤器拦截掉了或者是jar包冲突,只要报这个问题,你就先去找拦截器的问题,看是哪个拦截器拦截掉了,如果不是拦截器,那么就是jar包有冲突,可能是没引对,可能是老的jar包没有删。