讓ueditor和又拍雲搞基(form api,java)

又拍雲和ueditor集成 javascript

圖片上傳選擇又拍雲的form api,這種方式圖片上傳就直接走又拍雲服務器,不通過本身服務器。不過form api的sdk如今在又拍雲官網只有php版,java版的有一個android的form sdk,沒辦法,只能本身搞了。 php

又拍雲form api: html

要求: java

  1. 圖片上傳能夠指定任意文件夾
  2. 使用ueditor圖片上傳裏面的圖片上傳在線管理兩個功能


第一步:最簡單的試煉 jquery

根據官網api實例,若是用form的話須要policy,signature,file這幾個字段,action的路基爲又拍雲上傳圖片路徑加bucket android


"http://v0.api.upyun.com/"+data["bucket"]




<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  </head>
  <body>

    <form id="upyun_form" action="dd" 
	method="post" enctype="multipart/form-data">

      <!-- 須要傳遞如下三個表單內容 -->
      <input id="upyun_policy" type="hidden" name="policy" value="pl">
      <input id="upyun_signature" type="hidden" name="signature" value="si">
      <input type="file" name="file">
      <input type="submit" value="上傳">
			
    </form>
    <script type="text/javascript" src="/justforfun/lib/js/jquery.min.js"></script>  
    <script type="text/javascript" >
        $(function(){
            $.getJSON("/justforfun/upyun",function(data){
                $("#upyun_form").attr("action","http://v0.api.upyun.com/"+data["bucket"]);
                $("#upyun_policy").val(data["policy"]);
                $("#upyun_signature").val(data["signature"]);
            });
        });
    </script>  
    
  </body>
</html>


爲何要用ajax呢,由於文檔中說了,policy和signature須要壓縮加密,因此須要在後臺搞一下。加密的話下載官網上Android的SDK,借用裏面幾個文件。就是下面標紅的地方,由於我用的是spring MVC,搞json的時候用的是jackson這個包,不過sdk裏面用的是json-lib,所以修改了下Util那個文件裏面json的轉換方式,別的地方沒改。 web

ok,寫一個上傳的類。 ajax

參數說明: spring

callbackMethod 對應下面兩個方法,一個是get同步回調,一個是post異步回調,測試中post不知到爲何沒搞成功,所用用return-url。 apache

callBackUrl回調的絕對路徑:http://localhost:8080/XXX/upyun/callback

bucket沒必要解釋了,apiKey須要在又拍雲設置,首先啓用表單API功能,而後就可一得到密鑰了。

方法解釋:

getSignature是api裏面規定的,直接調用Util的signature方法,並將生成的policy和apiKey用&連接搞進去。

UpYunUtils.signature(policy + "&" + API_KEY);

getSaveKey是保存圖片時候的圖片保存在bucket下的文件夾名字加文件名,api中有幾種pattern,例如我使用的是32位隨機字符串+後綴 "{random32}{.suffix}"



genarateUpyunEntity則是最主要的方法,返回一個UpyunEntity是爲了能直接用spring MVC搞json方便來的。


package com.upyun;

import java.io.File;
import java.util.*;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * UEditor文件上傳輔助類,上傳至又拍雲。
 * 
 */
public class UpYunUploader {

	private static Log logger = LogFactory.getLog(UpYunUploader.class);
    //回調的方法,見又拍雲api
	private String callBackMethod;
    //回調時調用路徑,注意使用絕對路徑
	private String callBackUrl;
    //又拍雲的bucket
	private String bucket;
    //又拍雲bucket中的apikey
	private String apiKey;

	public UpYunUploader(String callBackMethod, String callBackUrl,
			String bucket, String apiKey) {
		super();
		this.callBackMethod = callBackMethod;
		this.callBackUrl = callBackUrl;
		this.bucket = bucket;
		this.apiKey = apiKey;
	}

	// TODO:save_flooder傳值
	public UpYunEntity genarateUpyunEntity(String saveFolder)
			throws UpYunException {
		String expiration = ((Long) (System.currentTimeMillis() / 1000 + 1000 * 5 * 10))
				.toString(); // 過時時間,必須大於當前時間
		String saveKey = getSaveKey(saveFolder, "{random32}{.suffix}");
		HashMap<String, Object> params = new HashMap<String, Object>();
		params.put(callBackMethod, callBackUrl);
		// TODO:DELETE
		logger.info("callBackUrl:" + callBackUrl);
		String policy = UpYunUtils.makePolicy(saveKey, expiration, bucket,
				params);
		String signature = getSignature(policy, apiKey);
		return new UpYunEntity(bucket, policy, signature);

	}

	public String getSaveKey(String saveFloder, String pattern) {
		return File.separator + saveFloder + File.separator + pattern;
	}

	public String getSignature(String policy, String API_KEY) {
		return UpYunUtils.signature(policy + "&" + API_KEY);
	}
}
package com.upyun;

import lombok.Data;

public @Data
class UpYunEntity {
	private String bucket;
	private String policy;
	private String signature;

	public UpYunEntity() {
		super();
	}

	public UpYunEntity(String bucket, String policy, String signature) {
		super();
		this.bucket = bucket;
		this.policy = policy;
		this.signature = signature;
	}

}

controller

這個controller是在我修改完ueditor以後的版本,所以爲了能方便指定保存的路徑,加了一個upYunSaveFolder的參數,和以前html裏面有點不太對應,湊合這看吧。邏輯就是這樣一個邏輯。圖片上傳前,須要服務器生成一個policy和signature的加密字段,裏面包含了apikey,保存路徑,這次操做過時時間等等。


package com.upyun;

import java.io.File;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;

import com.upyun.UpYun.FolderItem;

@Controller
@RequestMapping("/upyun")
public class UpYunController {
	private static Log logger = LogFactory.getLog(UpYunController.class);
	public static final String CALL_BACK = "/upyun/callback";
	@Resource
	private UpYunUploader uploader;
	@Resource
	private UpYun upYun;

	@RequestMapping(method = RequestMethod.GET, params = { "upYunSaveFolder" })
	public @ResponseBody
	UpYunEntity up(String upYunSaveFolder) throws UpYunException {
		return uploader.genarateUpyunEntity(upYunSaveFolder);
	}

	@RequestMapping("/callback")
	public @ResponseBody
	UeditorCallBackEntity callBack(UpYunCallBackEntity upyunImage,
			WebRequest request) {
		// TODO:delete
		logger.info(CALL_BACK + upyunImage);
		return new UeditorCallBackEntity(upyunImage);
	}

	@RequestMapping(value = "imageManager", params = { "upYunSaveFolder" })
	public @ResponseBody
	String imageManager(String upYunSaveFolder) {
		List<FolderItem> list = upYun.readDir(upYunSaveFolder);
		StringBuffer buffer = new StringBuffer();
		for (FolderItem fi : list) {
			buffer.append("/");
			buffer.append(fi.name);
			buffer.append("ue_separate_ue");
		}
		String imgStr = buffer.toString();
		if (!imgStr.equals("")) {
			imgStr = imgStr.substring(0, imgStr.lastIndexOf("ue_separate_ue"))
					.replace(File.separator, "/").trim();
		}
		// TODO:delete
		logger.info(imgStr);
		return imgStr;
	}
}


第二部:ueditor好基友

要的是這個框框啊最後。

原來的修改功能不要了,圖片上傳ueditor用的是swfupload,爲了和又拍雲整合,須要改下面幾個文件。(image那兩個文件在dialogs/image下)

  1. ueditor.all.js(上傳完成肯定後,取消點擊圖片後修改的連接)
  2. image.js(爲了可以根據不一樣的文件夾作在線管理,在原來的ajax那裏多傳了一個參數)
  3. image.html(爲了和又拍雲結合,將須要的參數傳過去,postParams裏面加了幾個參數,而且去掉了百度圖片搜索和圖片修改的html)
  4. ueditor.config.js(ueditor的配置文件,改了很多地方)

首先是config.js

在UEDITOR_CONFIG上面先存幾個變量,注意visitPath和uploadPath的區別.

訪問圖片時是visitPath+/文件夾/圖片.jpg


var upyunVisitPath = "http://practicephotos.b0.upaiyun.com/";
	var upyunUploadPath = "http://v0.api.upyun.com/";
	var BUCKET = "practicephotos";
	// saveFolder上傳到又拍雲的文件夾,應根據同用戶在session中或者什麼地方傳值,
	//注:saveFolder是爲了upYunSaveFolder和imageManagerPath而存在的臨時變量
	var saveFolder = "uploadimagetest";
	/**
	 * 配置項主體。注意,此處全部涉及到路徑的配置別遺漏URL變量。
	 * UEDITOR_CONFIG的配置均可以在js中動態修改
     * editor.options.XXX = ""
	 */
	window.UEDITOR_CONFIG = {
           

		// 爲編輯器實例添加一個路徑,這個不能被註釋
		UEDITOR_HOME_URL : URL,

imageFieldName改成「file」,對應的image.html中也有修改,由於又拍雲裏面圖片的字段必須是「file」。


// 圖片上傳地址:又拍雲上傳路徑加bucket
		imageUrl : upyunUploadPath + BUCKET 
		,
        //圖片修正地址,後臺會自動加上保存文件夾和圖片路徑/XXX/XXX.jpg
        //所以修正路徑只加上又拍雲的<strong>訪問路徑</strong>便可
		imagePath : upyunVisitPath // 圖片修正地址,引用了fixedImagePath,若有特殊需求,可自行配置
		// 集成又拍雲 須要修改這裏和image.html裏面的upfile
		,
		imageFieldName : "file" // 圖片數據的key,若此處修改,須要在後臺對應文件修改對應參數


注意在線管理裏面修正路徑與圖片上傳的不一樣。


// 圖片在線管理配置區
		// ,
		imageManagerUrl : projectName + "/upyun/imageManager" // 圖片在線管理的處理地址
		,
		//圖片管理修正路徑,與圖片上傳修正不一樣,後臺不會生成目錄,所以須要本身加生
		//<strong>訪問路徑</strong>和保存文件夾
		imageManagerPath : upyunVisitPath + saveFolder // 圖片修正地址,同imagePath
		,
ueditor.all.js,ctrl+f找圖片修改,找到下面的地方,str,上線的時候本身壓縮下js。



//TODO:若是還想要修改功能的話,下面註釋的東西應該放回去
                        //移除了圖片修改功能
                        //&nbsp;&nbsp;'+
                        //'<span onclick="$$._onImgEditButtonClick(\'' + dialogName + '\');" class="edui-clickable">' + editor.getLang("modify") + '</span>
                        str = '<nobr>' + editor.getLang("property") + ': '+
                            '<span onclick=$$._onImgSetFloat("none") class="edui-clickable">' + editor.getLang("default") + '</span>&nbsp;&nbsp;' +
                            '<span onclick=$$._onImgSetFloat("left") class="edui-clickable">' + editor.getLang("justifyleft") + '</span>&nbsp;&nbsp;' +
                            '<span onclick=$$._onImgSetFloat("right") class="edui-clickable">' + editor.getLang("justifyright") + '</span>&nbsp;&nbsp;' +
                            '<span onclick=$$._onImgSetFloat("center") class="edui-clickable">' + editor.getLang("justifycenter") + '</span></nobr>';
image.html


找到tabHeads,刪掉不要的東西。


<div id="tabHeads" class="tabhead">
	<span tabSrc="local" class="focus"><var id="lang_tab_local"></var></span>
	<span tabSrc="imgManager"><var id="lang_tab_imgManager"></var></span>
</div>

在下面隨便一個地方存一下兩個hidden的input,以知足又拍雲,固然,這不是用來上傳的。



<input id="upyun_policy" type="hidden" name="policy" /> 
<input id="upyun_signature" type="hidden" name="signature" />

在他原來的js上加一段ajax,注意imageFieldName改爲file,與config.js裏面對應。ajax傳的data裏面有一個upYunSaveFolder : editor.options.upYunSaveFolder,就是用這個變量來改變保存路徑的,如何調用後面再說。

<script type="text/javascript">
		$($.getJSON("/justforfun/upyun", data = {
			upYunSaveFolder : editor.options.upYunSaveFolder
		}, function(data) {
			$("#upyun_policy").val(data["policy"]);
			$("#upyun_signature").val(data["signature"]);
		}));
		//全局變量
		var imageUrls = [], //用於保存從服務器返回的圖片信息數組
		selectedImageCount = 0; //當前已選擇的但未上傳的圖片數量

		editor.setOpt({
			imageFieldName : "file",
			compressSide : 0,
			maxImageSideLength : 900
		});


傳遞表單的附加參數,須要postParams中加值(在$G("upload").onclick那裏)。首先在flashOptions中找到ext,註釋掉這一行,不知道爲何,只有註釋掉這行以後才能傳postParams裏面的參數。


var postParams = {
					"dir" : baidu.g("savePath").value,
					"policy" : $("#upyun_policy").val(),
					"signature" : $("#upyun_signature").val()
				};
image.js


在這裏搜imageManagerUrl,找到這個ajax,填上data{upYunSaveFolder這一行}。


ajax.request(editor.options.imageManagerUrl, {
                            timeout:100000,
                            action:"get",
                            data: {
                            	upYunSaveFolder: editor.options.upYunSaveFolder
                            },
                            onsuccess:function (xhr) {
前臺調用,一、初始話的時候能夠在getEditor的時候設置upYunSaveFolder,注意imageManagerPath必定要設置。二、在任何用到js的地方均可以修改editor.options.XXX屬性,這裏的話XXX就是upYunSaveFolder。



<script type="text/plain" id="editor" name="content" style="width: 680px;height:200px;">
 ${(content)!""}
</script>
<script type="text/javascript">
           var uySaveFloder ="test";
           var editor = UE.getEditor('editor',{wordCount:true,maximumWords:800,upYunSaveFolder:uySaveFloder,imageManagerPath:"http://practicephotos.b0.upaiyun.com/"+uySaveFloder});
           //editor.options.imageManagerPath="";
</script>
上傳成功以後又拍雲會返回又拍雲的一些狀態碼,和ueditor裏面的狀態碼並不對應。


首先是controller裏面的回調方法,再貼一下。至於@Data註解和爲何沒寫get set方法,請見lombok.

UeditorCallBackEntity狀態碼能夠參照ueditor裏面Upload.java和imageUp.jsp來搞。

UpYunCallBackEntity則根據又拍雲文檔裏面回調的東西來作。注意文檔中的那句話:加密的話即便是圖片空間也不會返回圖片寬高那些參數。


@RequestMapping("/callback")
	public @ResponseBody
	UeditorCallBackEntity callBack(UpYunCallBackEntity upyunImage,
			WebRequest request) {
		// TODO:delete
		logger.info(CALL_BACK + upyunImage);
		return new UeditorCallBackEntity(upyunImage);
	}
package com.upyun;

import lombok.Data;

/**
 * response.getWriter().print("{'original':'"+up.getOriginalName()+
 * "','url':'"+up.getUrl()+ "','title':'"+up.getTitle()+
 * "','state':'"+up.getState()+"'}");
 * */
public @Data
class UeditorCallBackEntity {
	private String original;
	private String url;
	private String title;
	private String state;

	public UeditorCallBackEntity(UpYunCallBackEntity upyunImage) {
		url = upyunImage.getUrl();
		state = transUpYunCodeToUeState(upyunImage.getCode(),
				upyunImage.getMessage());
	}

	private String transUpYunCodeToUeState(String code, String msg) {
		String defaultState = "未知錯誤";
		if (code == null) {
			return defaultState;
		}
		if (code.equals("200")) {
			return "SUCCESS";
		}
		return msg;
	}
}


package com.upyun;

import lombok.Data;

/**
 * {"code":200, "message":"ok", "url":"\/test\/1382948348613.jpg",
 * "time":1382948355, "image_width":900, "image_height":506, "image_frames":1,
 * "image_type":"JPEG", "sign":"fab7c454ea8e54efdeacaf2557c25f6d"}
 * 
 * */
public @Data
class UpYunCallBackEntity {
	private String code;
	private String message;
	private String url;
	private String time;
	private String sign;
}

在線管理

首先把又拍雲的java sdk搞下來,把裏面的UpYun放到工程裏面。配置一個bean,把以前的upYunUploader一塊兒貼在這。

在線管理,原來的imageManger.jsp裏面是遍歷上傳圖片的文件夾,而後會進行路徑處理,重寫這個方法。最初他會得到文件下的全部文件,而後字符串拼接成/XXX.jspue_separate_ue/XXX.jspue_separate_ue這種形式,還記得config.js裏面的在線管理圖片修正路徑麼?例如修正路徑AAA,ueditor最終會把/XXX.jspue_separate_ue/XXX.jspue_separate_ue處理成AAA/XXX.jsp AAA/XXX.jspue_separate_ue這種樣子。並且須要是個json。

controller處理方法

@RequestMapping(value = "imageManager", params = { "upYunSaveFolder" })
	public @ResponseBody
	String imageManager(String upYunSaveFolder) {
		List<FolderItem> list = upYun.readDir(upYunSaveFolder);
		StringBuffer buffer = new StringBuffer();
		for (FolderItem fi : list) {
			buffer.append("/");
			buffer.append(fi.name);
			buffer.append("ue_separate_ue");
		}
		String imgStr = buffer.toString();
		if (!imgStr.equals("")) {
			imgStr = imgStr.substring(0, imgStr.lastIndexOf("ue_separate_ue"))
					.replace(File.separator, "/").trim();
		}
		// TODO:delete
		logger.info(imgStr);
		return imgStr;
	}

至此,ueditor和又拍雲整合就結束了。圖片上傳的配置主要在image.html裏面。

相關文章
相關標籤/搜索