Bootstrap

ueditor上传文件到七牛云坑爹录

最近用了一下ueditor,版本是1.4.3,上传文件要上传到七牛,网上能找到的都是基于比较较旧的版本写的,比较痛苦,找半天也找不到一个可以参考的,百度的开源项目代码烂码农兄弟们大多心里是有数了的,就不多说了,坑都给坑到没了。

不多说,下面开始哈。


UEditor分为后端配置和前端配置


首先建议去下载它的源码来用,千万不要用百度打好的,下好源码后就放到你的项目里,包括两个部分,java和js





然后找到jsp里的config.json


这个文件找到以下这么一段描述,修改图片访问路径前缀为http://omf8899s1.bkt.clouddn.com/

/* 上传图片配置项 */
"imageActionName": "uploadimage", /* 执行上传图片的action名称 */
"imageFieldName": "upfile", /* 提交的图片表单名称 */
"imageMaxSize": 2048000, /* 上传大小限制,单位B */
"imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
"imageCompressEnable": true, /* 是否压缩图片,默认是true */
"imageCompressBorder": 1600, /* 图片压缩最长边限制 */
"imageInsertAlign": "none", /* 插入的图片浮动方式 */
"imageUrlPrefix": "http://omf8899s1.bkt.clouddn.com/", /* 图片访问路径前缀 */



然后找到ConfigManager.java这个类是管理加载你的配置信息的,也就是加载JSP下的config.json,死烂百度原来的代码是像下面这样的,死活都加载不了,然后报错。。。。

所以一定要修改正确这个配置文件加载路径


原来的如下:

/*
 * 通过一个给定的路径构建一个配置管理器, 该管理器要求地址路径所在目录下必须存在config.properties文件
 */
private ConfigManager ( String rootPath, String contextPath, String uri ) throws FileNotFoundException, IOException {
   
   rootPath = rootPath.replace( "\\", "/" );
   
   this.rootPath = rootPath;
   this.contextPath = contextPath;
   
   if ( contextPath.length() > 0 ) {
      this.originalPath = this.rootPath + uri.substring( contextPath.length() );
   } else {
      this.originalPath = this.rootPath + uri;
   }
   
   this.initEnv();
   
}

修改后的:

/*
 * 通过一个给定的路径构建一个配置管理器, 该管理器要求地址路径所在目录下必须存在config.properties文件
 */
private ConfigManager ( String rootPath, String contextPath, String uri ) throws FileNotFoundException, IOException {

   //rootPath = rootPath.replace( "\\", "/" );
   //rootPath = rootPath.replace( "\\", File.separator );
   this.rootPath = rootPath;
   this.contextPath = contextPath;

   if ( contextPath.length() > 0 ) {
      this.originalPath = this.rootPath + File.separator + "jsp" + File.separator + "config.json";
   } else {
      this.originalPath = this.rootPath + uri;
   }

   this.initEnv();

}

然后我们再来看看这个配置文件,ConfigManager.java其实就是加载这个配置文件 的,不加载是用不了的,而ConfigManager中的加载路径又不对,这是坑之一,最大的坑,是用来坑爹用的!!!





然后我们再来写上传文件的接口


package com.canplay.ryf.controller;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.canplay.ryf.base.ResultBean;
import com.canplay.ryf.service.IImageService;
import com.canplay.ryf.ueditor.ActionEnter;
import com.canplay.ryf.util.QiniuUtils;
import com.canplay.url.UrlCommand;
/**
 * 
 * @author mac
 * 管理员后台
 */
@Controller
public class UploadController {
   
   private boolean isTest = true;
   private Logger logger = LoggerFactory.getLogger(getClass());
   
   @Autowired
   private QiniuUtils qiniu; 
   
   
   @Autowired
   private IImageService imageService; 
   
   /**
    * 获取七牛TOKEN
    * 
    * @param request
    * @param response
    * @return
    */
   @RequestMapping(value = "getQiNuToken")
   @ResponseBody
   public ResultBean getQiNuToken(HttpServletRequest request, HttpServletResponse response) {
      ResultBean ret = new ResultBean();
      try {
         String token = qiniu.getUpToken();
         ret.setData(token);
         ret.setSuccess(true);
      } catch (Exception e) {
         e.printStackTrace();
         ret.setSuccess(false);
      }
      return ret;    
   }


   
   /**
    * 加载配置文件
    * @param request
    * @param response
    * @return
    * @throws JSONException 
    */
   @RequestMapping(value = "editorConfig")
   @ResponseBody
    public String editor (HttpServletRequest request,HttpServletResponse response) throws JSONException {
        try {
            request.setCharacterEncoding("utf-8");
            response.setHeader("Content-Type", "text/html");
            ServletContext application = request.getServletContext();/**这里就是UE的JS根目录**/
            String rootPath = application.getRealPath("/public/page/matchschool/3g/admin/ueditor");
            String result = new ActionEnter(request, rootPath).exec();
            return result;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }
   
   /**
     * 多文件上传支持 
     * @param upfile
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "uploadfile")
    public Map uploadFile(@RequestParam(value = "upfile", required = false) MultipartFile[] upfile,@RequestParam(value = "ownerId", required = false) String ownerId) throws Exception{
        Map<String,String> map = new HashMap<String, String>();
        if (upfile != null && upfile.length > 0){
            //循环获取file数组中得文件
            for(int i = 0;i<upfile.length;i++){
                MultipartFile file = upfile[i];
                String fileName = file.getOriginalFilename();
                byte[] fileByte = file.getBytes();
                //返回对象
                System.out.println("上传文件"+fileName);
                try {
                    Map<String, Object> qiNunRetMap = new QiniuUtils().uploadFile(fileByte,fileName);
                    imageService.insertImage(ownerId, qiNunRetMap.get("key")== null?"":qiNunRetMap.get("key").toString(), qiNunRetMap.get("hash")== null?"":qiNunRetMap.get("hash").toString(), 1);
                    map.put("url",fileName);
                    map.put("name",fileName);
                    map.put("state","SUCCESS");
                }catch (Exception e){
                    e.printStackTrace();
                    map.put("state","上传失败!");
                }
            }
        }
        return map;
    }
   
}

QiniuUtils.java


package com.canplay.ryf.util;

import com.canplay.ryf.enums.QiniuBucket;
import com.canplay.ryf.model.ImageEntity;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;

import freemarker.core.Macro;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * Created by lyj on 2016/8/19.
 */
@Service
public class QiniuUtils {
    //设置好账号的ACCESS_KEYSECRET_KEY
    String ACCESS_KEY = "UFtCym3NVt2e5nZFIzTlqOYzrTGmJTzTPt9x5BD";
    String SECRET_KEY = "N0lbgy8h7KyvkYQ2MIyfOWy9Bs0JP4hST2BMOpO";
    
    //密钥配置
    Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
    //创建上传对象
    UploadManager uploadManager = new UploadManager();

    //简单上传,使用默认策略,只需要设置上传的空间名就可以了
    public String getUpToken(){
       QiniuBucket.LIVE_IMG.getBucket();
       auth.uploadToken(QiniuBucket.LIVE_IMG.getBucket());
        return auth.uploadToken(QiniuBucket.LIVE_IMG.getBucket());
    }

    public Map<String, Object> upload(byte[] file,String key) throws IOException {
       Map<String, Object> map = new HashMap<String,Object>();
        try {
            //调用put方法上传
            Response res = uploadManager.put(file, key, getUpToken());
            //打印返回的信息
            System.out.println(res.bodyString());
            if (StringUtils.isNotEmpty(res.bodyString())) {
               map = JsonUtil.parseJSON2Map(res.bodyString());
         }
        } catch (QiniuException e) {
            Response r = e.response;
            // 请求失败时打印的异常的信息
            System.out.println(r.toString());
            try {
                //响应的文本信息
                System.out.println(r.bodyString());
            } catch (QiniuException e1) {
               e1.printStackTrace();
            }
        }
        return map;
    }

    /**
     * 上传文件
     * @param file byte
     * @param key 文件名
     * @throws Exception
     */
    public Map<String, Object> uploadFile(byte[] file,String key) throws Exception{
        return new QiniuUtils().upload(file,key);
    }
}

QiniuBucket.java

在七牛后台设置存储空间时会有下面的两个值的。

package com.canplay.ryf.enums;

/**
 * RYF七牛对应的空间名
 */
public enum QiniuBucket {

   /**
    * 头像模块
     */
   LIVE_IMG("ry45617", "http://omf8899s1.bkt.clouddn.com/");

   QiniuBucket(String bucket, String domain) {
      this.bucket = bucket;
      this.domain = domain;
   }

   private String bucket;
   private String domain;

   public String getBucket() {
      return bucket;
   }

   public void setBucket(String bucket) {
      this.bucket = bucket;
   }

   public String getDomain() {
      return domain;
   }

   public void setDomain(String domain) {
      this.domain = domain;
   }
}

要在前端页面使用,还要看一下ueditor.config.js,// 服务器统一请求接口路径
        serverUrl:"/ryf/editorConfig"  对应的是 UploadController 的editor方法




前端html页面


<script type="text/javascript">
var ownerId = "";
$(document).ready(function() {
   //随机生成一个所属ID给图片
   ownerId = Math.floor(Math.random()*1000000+1)
    //实例化编辑器
    var ue = UE.getEditor('editor');
    UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
    UE.Editor.prototype.getActionUrl = function(action) {
        if (action == 'uploadimage' || action == 'uploadscrawl' || action == 'uploadimage'
                || action == 'uploadvideo' || action == 'uploadfile') {
            return '/ryf/uploadfile?ownerId='+ownerId;
        }else {
            return this._bkGetActionUrl.call(this, action);
        }
    }
    
    $('#btn').click(function(event) {
        ue.ready(function(){
        var html = ue.getContent();
        var param= {
            content : html,
            ownerId : ownerId
        }
        $.ajax({
                type: "post",
                url: '/ryf/addLive',
                data : param,
                dataType: "json",
                success: function(result) {
                        if(result.success){
                            alert('提交成功', -1);
                            ue.execCommand('cleardoc');
                        }
                }
          });
        
     })
    });
    
});
</script>


如果在上传图片的同时提交其他参数,比如图片的ownerId,应该在URL后面加?直接拼,不要去修改UE的源码,吃力不讨好的,具体参考以下这行

/project/uploadfile.action?ownerId=

其次需要点明一下的是

uploadfile.action

对应的其实就是UploadController中的uploadFile方法。



;