查看相关资料,请点击下面的链接:

了解七牛云

了解UEditor CKEditor 网页编辑器


七牛 允许 html/js 直接上传,通过其提供的js工具可方便地完成,也可以自己写逻辑实现,不过其有写要求如上传文件的字段名称为 "file",自定义的变量字段加 "x:",需要附加token,需要post请求等,更详细的参数及说明请点击查找对应的官方说明


UEditor整合七牛

我本想直接通过指定ue的一些参数可以直接将文件上传到七牛,无奈,居然没有发现ue有相关配置,ue的做法是设置了统一的服务端请求定制,即自带的controller.jsp,其所有的逻辑都依赖此jsp,不允许进行其它服务器的扩展,不愿意改其js源码,于是走了第二条路:将上传到自己网站的图片通过java代码再上传到七牛云,即作一次文件中转,虽然有损性能和网络资源,不过也倒能接收,重要的是实施简单,只要找到其保存到本地文件的代码,使用七牛的java客户端读取该文件上传到七牛即可,上传完毕后删除ue保存到本地的文件。

下载ue的java源码:下载其包含源码的版本,解压可得到其java源码(hecontroller.jsp在一个目录,很容易找到的)

通过文章开始的资料文章,我们已经知道 ue后端是通过 com.baidu.ueditor.upload.StorageManager#saveTmpFile 来保存到本地的,所以我们就在这个地方进行扩展,无奈 ue的java源码居然全部是 类的静态方法调用,丝毫没有可扩展性(静态调用下,java的多态性将无用武之地),只能修改源码了:

为了最小化修改其源码,我将此方法的调用委托到了另外一个类里,两处TODO标记出了修改的地方:

public static UEQiNiuUtil ueQiNiuUtil;//TODO: Qi Niu process HOOK
	private static State saveTmpFile(File tmpFile, String path) {
		if (ueQiNiuUtil != null) {//TODO: Qi Niu process HOOK
			return ueQiNiuUtil.saveTmpFile(tmpFile, path);
		}

		State state = null;
		File targetFile = new File(path);

		if (targetFile.canWrite()) {
			return new BaseState(false, AppInfo.PERMISSION_DENIED);
		}
		try {
			FileUtils.moveFile(tmpFile, targetFile);
		} catch (IOException e) {
			return new BaseState(false, AppInfo.IO_ERROR);
		}

		state = new BaseState(true);
		state.putInfo( "size", targetFile.length() );
		state.putInfo( "title", targetFile.getName() );
		
		return state;
	}
上文中,通过设置ueQiNiuUtil表示要走到 七牛 的处理流程中,若不设置则走原有流程。

接下来所有的工作都到 UEQiNiuUtil中去做了:

package com.baidu.ueditor.qiniu;


import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.State;
import com.baidu.ueditor.upload.StorageManager;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.Properties;

public class UEQiNiuUtil {
    public String ak;
    public String sk;
    public String bucket;
    public UploadManager uploadManager;

    private static boolean inited = false;
    public static synchronized void init() {
        if (inited) return;
        try {
            inited = true;
            Properties properties = new Properties();
            properties.load(UEQiNiuUtil.class.getResourceAsStream("/qiniu.properties"));
            UEQiNiuUtil ueQiNiuUtil = new UEQiNiuUtil();
            ueQiNiuUtil.ak = properties.getProperty("qiniu.ak");
            ueQiNiuUtil.sk = properties.getProperty("qiniu.sk");
            ueQiNiuUtil.bucket = properties.getProperty("qiniu.bucket");
            ueQiNiuUtil.uploadManager = new UploadManager();
            StorageManager.ueQiNiuUtil = ueQiNiuUtil;//TODO: add hook to UE
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public State saveTmpFile(File tmpFile, String path) {
        File targetFile = new File(path);
        String fileName = targetFile.getName();

        try {
            uploadFileToQiNiu(fileName, tmpFile.getCanonicalPath());

        } catch (IOException e) {
            e.printStackTrace();
            return new BaseState(false, AppInfo.IO_ERROR);
        } finally {
            FileUtils.deleteQuietly(tmpFile);//删除临时文件
        }

        State state = new BaseState(true);
        state.putInfo("size", tmpFile.length());
        state.putInfo("title", fileName);

        return state;
    }

    public String getUptoken() {
        // TODO: should be cached for performance
        String uptoken = Auth.create(ak, sk).uploadToken(bucket);
        return uptoken;
    }

    public void uploadFileToQiNiu(String fileKey, String file) {
        try {
            Response response = uploadManager.put(file, fileKey, getUptoken());
            // see response
        } catch (QiniuException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        UEQiNiuUtil ueQiNiuUtil = new UEQiNiuUtil();
        ueQiNiuUtil.init();
        ueQiNiuUtil.uploadFileToQiNiu("aabbcc", "/home/conquer/Desktop/baidu.png");
    }
}



关于 qiniu.propertiest的介绍,请查看文章开始提供的资料。

public State saveTmpFile(File tmpFile, String path) 这个方法就是修改后要执行的方法,修改逻辑很简单,就是将ue的缓存文件上传到七牛,并删除缓存文件。

使用 七牛 存储 UE的图片,还需要修改

1.config.json  :"imageUrlPrefix": "http://7xrxxq.c0m2.z0.glb.clouddn.com/", /* 图片访问路径前缀 */

改为自己的七牛账号中的域名

2.网站启动后调用一次:

UEQiNiuUtil.init();// 开启 七牛上传
通常可以嵌入到包含ue的页面内部,如:
<%@ page import="com.baidu.ueditor.qiniu.UEQiNiuUtil" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    UEQiNiuUtil.init();// 开启 七牛上传
%>
<!DOCTYPE html>

CKEditor整合七牛

尝试ckeditor的form直接上传图片到七牛(up.qiniu.com),然而ckedi的表单我们拿不到,这样我们就很难添加自定义的参数,比如七牛需要的 token 参数,索性直接将其拼接到了 form表单中指定(up.qiniu.com?token=xxxxx),另外一个问题是七牛需要的上传文件的字段为 "file",而ck的字段为 "upload",无奈没有配置项,只能修改ckeditor.js修改其源码,继续尝试图片终于可以上传到七牛了,然而七牛的返回值 ck无法识别,文章开始时提供的资料里,说明里dk需要的是 一段 jsonp的 script 脚本回调,而 七牛通过 returnBody指定的返回内容只能是 json 格式的,这里是无法修改七牛的返回值的,这样,ck直接上传到七牛的路也走不通了,于是和 UE一样选用了文件中转上传到七牛的方式,其细节与ue差不多,不详述了。


Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐