UEditor 自定义上传 远程服务器

时间:2024-04-02 08:33:40

终于是搞定了UEditor自定义上传...

上班的时间写这个,不知道会不会被骂死...

现在公司正在做的一个项目,需要用到HTML编辑器,在UEditor之前,使用的是Ckeditor+Ckfinder。

CK这个编辑器和UEditor一样,都是首次使用,所以在网上也翻了写资料,发现大家都只是本地服务器上传。

但项目有个要求:图片文件,需要上传至图片服务器,需要使用的时候也从图片服务器上下载,这样可以相对减轻web服务器的压力,也使文件资源更安全,使用更灵活。

那么需求提出来,就开始做了,CK是国外的富文本编辑器,找了很多资料,都是English看的是脑袋发胀(大家英语应该学好)。

后面才看到一段官方的回答,外国码友提问的,大意是:ck是否支持上传到远程服务器。得到的官方回答是不支持,需要自己去重写某东西。

在寻找CK资料的时候有瞄到UEditor。

虽然有自己扩展了CK的图片上传,但是有两个问题:

1、扩展的图片上传,使用图片上传,它不去调用设置的controller(框架是SpringMVC),直接把文件上传到本地服务器;

2、直接修改文本编辑器本身自带的图片上传功能,从服务器上获取图片列表后,不知道如何把图片嵌入文本编辑器中(因为需要直接做一个页面来展示这些图片);

 

这也是最终放弃的原因,不知道哪里没有配置,或者配错,也找不到类似资料,再研究下去太花时间,于是在看到官方回答后,决定放弃。

上周五下午就下载了UEditor,但是本人有个坏习惯,就是不喜欢看文档,然后就开始瞎搞。

昨天在UEditor群里问了点问题,但似乎都没有人做和一样的需求,找了很多资料也都只是简单的本地服务器上传。

那么现在把实现的方式介绍给大家,使用的是最新的UEditor版本1.4.3.1,建议大家去官网下载。

1、下载UEditor后,解压,把它放到工程里,还有它的Jar包也要放进去,1.4.3.1结构是这样的

UEditor 自定义上传 远程服务器

Jar包放在WEB-INF/lib下面

UEditor 自定义上传 远程服务器

===================================

A、先讲前端

===================================

2、在你的全局脚本jsp中或者你需要用UEditor的jsp中引入UEditor的js

<scripttype="text/javascript"charset="utf-8"src="${yourPath}/ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8"src="${yourPath}/ueditor/ueditor.all.min.js"></script>
<script type="text/javascript"charset="utf-8"src="${yourPath}/ueditor/lang/zh-cn/zh-cn.js"></script>

这时候已经可以开始使用UEditor了

3、在Jsp中使用,在你需要放编辑器的地方插入下面的语句

UEditor 自定义上传 远程服务器

第一行script就是UEditor面板,你只需要修改name就行,对应的是表单的name(此时表单中就不需要设置了,它就代表你表单的那一项)

第二行脚本域里面,实际上就是自定义上传的核心,var ue = UE.getEditor('editor'); 就是创建面板用的,一定要有;如果不使用自定义上传,那么下面的也就不需要了,只要创建面板那一句就够了。

简单介绍:

UE.Editor.prototype._bkGetActionUrl=UE.Editor.prototype.getActionUrl; 是用来获取Action的,照写就行,然后就是下面的 UE.Editor.prototype.getActionUrl=function(action){....}  这里面的if语句,就是用来设置自定义action的,这里叫Controller,Struts2里面才叫action;

下面先看看,ueditor下jsp里面的config.json,以下截取的一部分,看这些就够了,

你会发现,下面有个imageActionName,这个xxxxActionName,开始以为是需要把自定义上传Controller设置在这边,所以我点击上传的时候就报,错误的Action还是未知的Action  忘了它是怎么提示的,反正意思就是,你的Action不正确,实际上这是UEditor默认的Action,上面我们有看到 if (action == 'uploadimage' ||action== 'uploadscrawl' || action == 'uploadimage') {....} else if(action =='uploadvideo') {....} else if(action == 'listimage'){....} else{returnthis._bkGetActionUrl.call(this, action);}}

if语句里面的这些,对应的就是默认的action名称,说到这里,大家应该知道了吧, 要自定义上传什么就在这个script里面加if语句来判断即可,实在没有,它就返回       this._bkGetActionUrl.call(this,action);  这个东西我想你应该要有,否则没找到你设置的action它本地也上传不了。

======================config.jsonStart========================================

UEditor 自定义上传 远程服务器

======================config.jsonEnd==========================================

那么,这样在前端就已经介绍完。

 

===================================

B、接下来看看后端

===================================

后端Controllerd代码直接贴出来,因为图片上传不了,这个CSDN有问题啊!!

以下是Controller层方法,以图片上传为例,这边只需要图片上传,其它的就不贴了。

这里代码还没优化。

多图上传也是调用这个方法即可。

=======================ControllerStart=====================================================

/**
* 上传图片
*
* @return
* @throws IOException
* @throws IllegalStateException
* @RequestParam("upload")MultipartFile file,
*/
@RequestMapping(value ="upload")
public String uploadImage(
HttpServletRequest request,HttpServletResponse response)
throws IllegalStateException, IOException{
response.setContentType("text/html;charset=UTF-8");
ReturnUploadImage rui = null;//这个是UEditor需要的返回值内容,UEditor要的返回值需要封装成Json格式
// 转型为MultipartHttpRequest:
MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest) request;
// 获得文件:
MultipartFile file =multipartRequest.getFile("upfile"); //UEditor传到后台的是这个upfile,其他的文件上传,应该也差不多是这个,还没去研究,断点一下就知道了
// 写入文件
File imageFile =newFile("/"+Uuid()+".jpg");
file.transferTo(imageFile);
//现在获取了File接下来要上传到OSS上
if(imageFile!=null){
rui = new ReturnUploadImage();
rui.setTitle(imageFile.getName());//这里需要设置文件名称如:xxx.jpg
rui.setOriginal(imageFile.getName());//这里需要设置文件名称如:xxx.jpg
// 判断文件是否为图片文件
String r =ImageUtils.fileDetermine(imageFile, 3 * 1024);
if (!StringUtils.isNotEmpty(r)) {
// 上传文件(这里文件类型,要根据实际上传的类型去做,暂时是直接设置了.jpg,并且先保存到磁盘,这样对磁盘比较伤,每次上传都要先保存到磁盘,然后再删除)
ResultInfo resultInfo = OSSObjTools.uploadObject(imageFile,
"subWebPublicNotice");//这里是自己封装的OSS,上传到OSS上面
// 判断如果返回结果不为空并且MD5返回值比较结果正确,就设置文件路径保存到数据库
if (resultInfo != null
&&resultInfo.geteTag().equalsIgnoreCase(
MD5Tools.file2MD5(imageFile))) {
rui.setState("SUCCESS");//这里上传成功的话一定要设置大写的 SUCCESS,失败还没测试,猜应该是FAIL,回头再去官网找找
rui.setUrl(CommonTools.catchUrlPath(PubParam.BUCKET_NAME,
PubParam.Mark_ShenZhen) +resultInfo.getFilePath());//这里是设置返回给UEditor的图片地址
}
}
// 判断临时存放的文件是否存在
if (imageFile.exists()) {
// 删除临时存放的文件
imageFile.delete();
}
}
String result = JSON.toJSONString(rui);//这边就是为了返回给UEditor做的格式转换
response.getWriter().write(result);
return null;
}

=======================ControllerEnd=====================================================

下面介绍一下返回给UEditor的参数

这里你应该参考http://fex.baidu.com/ueditor/#dev-request_specification

官方文档里面的 后端请求参数-请求规范,

官方有介绍了,返回参数的格式,格式中json的key就是对应了类ReturnUploadImage里面的属性。

转换后格式应该是这样的,要严格按照文档上面的格式

{"original":"5dfcfea3e3b442bda3972053266c3bd3.jpg","state":"SUCCESS","title":"5dfcfea3e3b442bda3972053266c3bd3.jpg","url":"http://www.xxxxx321.com/mmmm/xxxModuleName/20150922/5dfcfea3e3b442bda3972053266c3bd3.jpg"}

注:不同的文件上传,返回的属性不一样

=======================ReturnUploadImageStart============================================

public classReturnUploadImage {
private String state;//上传状态SUCCESS 一定要大写
private String url;//上传地址
private String title;//图片名称demo.jpg
private String original;//图片名称demo.jpg

....getter & setter...

}

=======================ReturnUploadImage End==============================================

这里官方文档也说的很清楚,对应 config、uploadimage、uploadscrawl、uploadvideo、uploadfile....都有各自的格式

文档里面这些对应的就是xxxxActionName

官方文档截图:

UEditor 自定义上传 远程服务器

至此,UEditor的图片上传介绍结束

在线管理的话,需要你从服务器获取图片地址等信息,按官方的 请求格式规范 返回到页面给UEditor即可

下面是效果图

上传:

UEditor 自定义上传 远程服务器

2、上传结果

UEditor 自定义上传 远程服务器

3、在线管理

UEditor 自定义上传 远程服务器

 

 前端部分再补充一点
在生产环境中,可能会有修改该内容的时候,如果按照上面的前端写法,在数据回显上会有 无法将数据库中内容回显到编辑器面板中的问题;
对此问题,做如下修改:
1、把第一行脚本干掉,换成你的 textarea, textarea的id不变(反正只要跟下面创建编辑器用的那个id一样即可)

UEditor 自定义上传 远程服务器
为什么这样做?因为创建编辑器面板有三种方法

第一种:本文开头前端第3点讲里面的第一行 script 脚本是用来创建编辑器;

第二种:不需要第一行script脚本,而是在第二行 var ue = UE.getEditor('editor');下面添加 ue.render('textareaID'); 这个textareaID就是对应了你的textarea,UEditor会把它“变成”编辑器;

第三种,既然可以这样,那就应该可以直接使用 var ue = UE.getEditor('textareaID'); 试了一下,果然可以。

这三种都有问题:

第一种问题是:在做类似修改的操作时,从数据库获取的数据,通过正常的返回,编辑器中无法显示内容;

第二种问题是:使用“render”可以实现在编辑器中显示内容,但当点击图片上传的时候,图片上传面板却跑到编辑器下面一层,被编辑器挡住,或者被遮罩层挡住;如果要解决这个问题,应该不是去修改UEditor的样式吧,如果是这样,那么这个工具就显得很low;

第三种问题是:可以正常在编辑器中显示内容,并且图片上传面板什么的也显示正常,只是编辑器变小了,也就是面板就不会自动初始化 宽1000、高320,于是看下一步解决这个问题;

2、在ueditor.config.js中找到
UEditor 自定义上传 远程服务器
把他们前面的注释去掉,虽然官方说默认是 W1000 H320,可能是样式还是什么的问题,需要去掉注释**它。
这样就可以成功回显了。