ueditor上傳圖片到七牛雲存儲(form api,java)

ueditor上傳圖片到七牛雲存儲

重要說明,本人已不作java多年,請不要加qq再問我java的東東,歡迎提問python。javascript

ueditor結合七牛傳圖片

傳統上,圖片是存在本身的服務器上(圖片->本身服務器),若是使用了雲存儲以後,有兩種方式存到雲端:css

  • (圖片->本身服務器->雲存儲)
  • (圖片->雲存儲) 明顯第二種節省本身服務器的壓力,結合七牛來講就是使用七牛的form api。

不少開發網絡應用的用戶須要從他們本身的客戶端訪問七牛雲存儲。傳統上,用戶會將數據上傳至他們的業務服務器,而後由業務服務器轉發至雲存儲。這種作法增長了客戶業務服務器的壓力,而且增長了用戶的流量成本。七牛雲存儲容許用戶從客戶端直接上傳數據,而無需到業務服務器中轉。這種模式具備更普遍的用途和靈活性。html

在客戶端直接上傳數據的基礎上,爲方便用戶業務服務器和客戶端的信息交互,七牛雲存儲還提供了回調業務服務器的功能。用戶能夠在一次數據上傳請求中,完成客戶端和業務服務器的數據交換。在此基礎上,七牛雲存儲還容許用戶利用魔法變量和自定義變量設定回調中所傳遞的數據。java

七牛的試煉

此次使用七牛SDK中的一些東西,結合jsp完成ueditor和七牛的結合。 項目放在osc@git上,能夠下載源碼對照查看。 http://git.oschina.net/duoduo3_69/QiNiuWithUeditor.gitpython

###開發前的準備與注意事項說明jquery

1.請將tomcat中server.xml裏面context的path改成"",這樣訪問時你的站點訪問地址爲http://你的域名/,(注意沒有工程名字),例如:git

<Context docBase="QiNiu" path="" reloadable="true" source="org.eclipse.jst.jee.server:QiNiu"/></Host>

2.由於ueditor上傳文件使用的是swfuplod,使用雲存儲回調是flash須要查找你的網站有沒有crossdomain.xml,因此請在WebContent放一個crossdomain.xml,這裏提供一個簡單的配置,若是有別的需求能夠自行定製。ajax

<?xml version="1.0"?>  
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" />
<allow-http-request-headers-from
	domain="*" headers="*" />
</cross-domain-policy>

Let's rock

##與ueditor結合前的準備工做apache

###首先從表單開始json

<form method="post" action="http://up.qiniu.com/" enctype="multipart/form-data">
  <input name="key" type="hidden" value="<resource key>">
  <input name="x:<custom_field_name>" type="hidden" value="<custom value>">
  <input name="token" type="hidden" value="<token>">
  <input name="file" type="file" />
  ...
</form>

這段代碼是七牛api裏面給的,結合七牛的文檔能夠看出,表單api必須有兩個字段,一個是token,一個是file,file也就是文件,token簡單的說就是七牛驗證你身份的一個加密編碼的串,七牛上傳的圖片的action就是http://up.qiniu.com/。

在此輸入圖片描述

###生成token token的生成有一套規則,官網api有介紹,結合七牛java的sdk很是簡單就能夠搞定。 首先把sdk中須要的東西搞出來,由於不會用到裏面全部的類,並且七牛sdk裏面分了好多包,本身的項目七牛全部的東西我都扔在com.qiniu下,看着比較順眼。

七牛的sdk 在此輸入圖片描述

須要用到的類和依賴的jar包(sdk是maven搞的,會自動下載,拖過來就行) 在此輸入圖片描述 在此輸入圖片描述

ok,找到裏面的Config.java

public class Config {
	
	public static String USER_AGENT;
	
	/**
	 * You can get your accesskey from <a href="https://dev.qiniutek.com"
	 * target="blank"> https://dev.qiniutek.com </a>
	 */
	public static String ACCESS_KEY = "<Please apply your access key>";

	/**
	 * You can get your accesskey from <a href="https://dev.qiniutek.com"
	 * target="blank"> https://dev.qiniutek.com </a>
	 */
	public static String SECRET_KEY = "<Apply your secret key here, and keep it secret!>";

	public static String RS_HOST = "http://rs.qbox.me";

	public static String UP_HOST = "http://up.qbox.me";
	
	public static String RSF_HOST = "http://rsf.qbox.me";

}

把ACCESS_KEY,和SECRET_KEY這兩個東西給填上,登陸七牛,不要選擇空間,而後點擊帳號設置就會看到密鑰,粘到這個裏面。 在此輸入圖片描述

###創建圖片空間 下一步在七牛空間裏建一個空間,專門來存圖片,請將空間設置爲公開空間,根據七牛的規則,公開空間裏面的文件都是外鏈直接能夠訪問的,而私用空間想要下載須要費一番功夫。由於咱們須要把圖片存在雲裏面供別人訪問,因此將這個空間設置爲公開便可。例如個人空間爲duoduo。 在此輸入圖片描述

###生成token 在sdk裏面會發先有test這一組測試用的包,其中有一個Uptoken,這個就是用來生成token的,將裏面的bucketName設置爲你的圖片空間,例如個人是duoduo。PutPolicy裏面的參數請參照官網api。

package com.qiniu;

import java.util.UUID;

import org.json.JSONException;

import com.qiniu.Mac;
import com.qiniu.Config;
import com.qiniu.PutPolicy;

public class Uptoken {
	public final static String makeUptoken() throws AuthException,
			JSONException {

		Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
		String bucketName = "duoduo";
		PutPolicy putPolicy = new PutPolicy(bucketName);
		// 能夠根據本身須要設置過時時間,sdk默認有設置,具體看源碼
		// putPolicy.expires = getDeadLine();
		putPolicy.returnUrl = "http://127.0.0.1/QiNiuCallback.jsp";
		putPolicy.returnBody = "{\"name\": $(fname),\"size\": \"$(fsize)\",\"w\": \"$(imageInfo.width)\",\"h\": \"$(imageInfo.height)\",\"key\":$(etag)}";
		String uptoken = putPolicy.token(mac);
		return uptoken;
	}

	/**
	 * 生成32位UUID 並去掉"-"
	 */
	public static String getUUID() {
		return UUID.randomUUID().toString().replaceAll("-", "");
	}
}

###上傳流程 七牛的上傳流程以下圖

在此輸入圖片描述

用戶上傳後,七牛怎樣將上傳結果返回給用戶呢?有兩種方式,簡單的說一個是get方法傳值,一個是post傳值。returnUrl用的就是get(301跳轉),而callbackUrl 則是post(異步回調)。

在此輸入圖片描述 在此輸入圖片描述

能夠看到我在Uptoken使用的是returnUrl,注意這裏要寫絕對路徑*,而returnBody裏面能夠參照api來設置,我在這裏取了文件上傳前的名字(name),如今的名字(key),並把他們拼成了json的格式,實際上僅僅須要key就能夠和ueditor集成。另外,policy裏面的deadline不須要操心,sdk裏面有默認的設置,固然你也能夠自行設置,不過注意,時間必定要大於當前時間

putPolicy.returnUrl = "http://127.0.0.1/QiNiuCallback.jsp";
putPolicy.returnBody = "{\"name\": $(fname),\"size\": \"$(fsize)\",\"w\": \"$(imageInfo.width)\",\"h\": \"$(imageInfo.height)\",\"key\":$(etag)}";

##集成ueditor ok,準備工做完畢,開始集成ueditor,上官網下載最新的jsp版本,當前爲1.2.6.1 Jsp ,utf8版。解壓,扔在項目裏面WebContent。

找到ueditor.config.js這個配置文件,更改一些配置,使ueditor與七牛結合。

首先是URL,這是爲了讓項目能找到ueditor裏面的一些文件,還記得注意事項裏面說的將server.xml更改的問題嗎,就是爲了/ueditor/準備的,固然你也能夠自行配置,不過可能會遇到一些路徑的問題,好比returnUrl。

var URL = window.UEDITOR_HOME_URL || "/ueditor/";

而後是圖片上傳的部分,imageUrl就是七牛傳圖片的地址是http://up.qiniu.com/,imagePath則是用戶訪問圖片的一個修正路徑,從哪裏找呢?在設置的圖片空間(duoduo)裏面的空間設置->域名設置那裏查看,如圖。七牛須要兩個字段,一個是file,一個是token,file在ueditor中須要設置兩次,第一次是在這裏設置,第二次和token都在image.html裏面設置,後面會說。

//圖片上傳配置區
    ,imageUrl:"http://up.qiniu.com/"            //圖片上傳提交地址
    ,imagePath:"http://duoduo.u.qiniudn.com/"                     //圖片修正地址,引用了fixedImagePath,若有特殊需求,可自行配置
    //七牛結合須要改爲file
    ,imageFieldName:"file"

在此輸入圖片描述

下一步,在index.html裏面顯示ueditor,沒什麼說的,代碼以下。

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>ueditor 七牛</title>
	<link rel="stylesheet" type="text/css" href="/QiNiu/ueditor/themes/default/css/ueditor.css"/>
	<script type="text/javascript" src="/QiNiu/ueditor/ueditor.config.js"></script>
	<script type="text/javascript" src="/QiNiu/ueditor/ueditor.all.js"></script> 
</head>
<body>
	<div style="width:800px;margin:20px auto 40px;">
		<script type="text/plain" id="editor" name="content" style="width:100%;height:200px;"></script>
	</div>
	<script type="text/javascript">
		UE.getEditor('editor')
   </script>
</body>
</html>

接下來,在ueditor/dialogs/image下找到image.html,這是圖片上傳的配置文件,image文件夾底下的東西都是和圖片上傳有關的,若是須要更高級的配置,請參照源碼(image.js),結合ueditor.config.js裏面的參數,進行操做。

image.html在這個文件加載的時候,咱們須要從後臺Uptoken那裏拿到此次上傳的token(token每次上傳都是不同的,由於他會自動加上deadline進行Base64編碼),使用ajax,我用的是jquery。在image.html裏面加了一個hidden的input框,暫時存一個變量,也就是須要傳給七牛的token。

<input id="qiniu_token" type="hidden" name="token" />

而後找到下面的標籤,ajax取值,這裏用的是一個Uptoken.jsp,後面介紹。注意我貼上的代碼editor.setOpt部分有一個變量imageFieldName:"file",這就是file的第二次修改地方。

<script type="text/javascript">
	$(function(){
		$.get("/QiNiu/Uptoken.jsp", function(data) {
			$("#qiniu_token").val(data["token"]);
		});
	});
    //全局變量
    var imageUrls = [],          //用於保存從服務器返回的圖片信息數組
        selectedImageCount = 0;  //當前已選擇的但未上傳的圖片數量

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

ueditor怎麼在圖片上傳的時候傳附加的參數呢?首先找到utils.domReady(function()這個部分地下的ext:'{"param1":"value1", "param2":"value2"}',,把這行註釋掉,覺得之前用的時候若是這行沒註釋本身的附加值傳不過去。往下找在 $G("upload").onclick = function () {裏面找到postParams,加上你想傳的參數。

var postParams = {
                "dir":baidu.g("savePath").value,
                "token":$("#qiniu_token").val()
            };

下面介紹上傳和回調有關的兩個jsp

* Uptoken.jsp,這是爲了得到uptoken,而且把token包成json的。
* QiNiuCallback.jsp,七牛returnUrl的回調地址,須要將七牛的狀態碼轉換爲ueditor的狀態碼,這樣才能正確顯示。

Uptoken.jsp,使用org.json-chargebee-1.0.jar這個包,這是sdk裏面自動下的。而後調用 Uptoken.makeUptoken()取到token放到json裏面,ok。

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<%@ page import="com.qiniu.*,org.json.JSONObject"%>
<%
	request.setCharacterEncoding("utf-8");
	response.setCharacterEncoding("utf-8");
	response.setContentType("application/json");
	JSONObject json = new JSONObject();
	json.append("token", Uptoken.makeUptoken());
	response.getWriter().print(json.toString());
%>

如今你就能夠上傳了。傳圖以前,打開狐火firebug,查看網絡面板裏面查看網絡的信息,當你點擊開始上傳按鈕以後,就會看到網絡面板裏面七牛以301get方式回調你當時returnUrl裏面設定的地址,打開七牛的空間能夠看到你上傳成功的圖片。

QiNiuCallback.jsp,圖片上傳以後七牛主要有兩種狀態,一種是成功,一種是失敗,成功就會按照你在policy裏面設置的returnBody的格式回調,若是失敗,則會返回一個json格式相似{"error":"錯誤信息"},而ueditor裏面須要一個json格式的state來告訴他圖片上傳的狀態,若是state是"SUCCESS",則ueditor認爲這次上傳成功,其他狀態均爲失敗。因此個人回調jsp以下。

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<%@ page import="com.qiniu.*,org.json.JSONObject"%>
<%
	request.setCharacterEncoding("utf-8");
	response.setCharacterEncoding("utf-8");
	String upload_ret = request.getParameter("upload_ret");
	JSONObject callback = new JSONObject(Base64Coder.decode(upload_ret));
	JSONObject json = new JSONObject();
	if (callback.has("error")) {
		json.put("state", callback.get("error"));
	} else {
		json.put("original", callback.get("name"));
		json.put("url", callback.get("key")+"-v001");
		json.put("state", "SUCCESS");
	}
	response.getWriter().print(json.toString());
%>

在這裏加了一個"v001",json.put("url", callback.get("key")+"-v001");這是什麼呢?七牛會存你上傳的原圖,若是原圖過大,顯示效果可能不會很好,所以,可使用七牛的縮略圖功能。首先新建一個v001的縮略圖模板(名字隨便起)。在空間的數據處理,圖片處理那個位置。 設置了縮略圖以後怎麼訪問呢?就是原圖的外鏈地址加上樣式分隔符加上縮略圖模板名字,例如圖片的key爲XXXAAA,樣式分隔符爲-,模板名爲v001,則縮略圖url爲XXXAAA-v001。

在此輸入圖片描述

另外Base64Coder.decode這個是解碼的類,由於七牛在回調的時候回調的字符串也通過了Base64編碼。sdk裏面沒找到解碼的方法,須要加上這個解碼的類,代碼以下。

package com.qiniu;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;

public class Base64Coder {

	public static String decode(String s) {
		return StringUtils.newStringUtf8(Base64.decodeBase64(s));
	}

	public static String encode(String s) {
		return Base64.encodeBase64String(StringUtils.getBytesUtf8(s));
	}
}

至此,圖片本地上傳功能結束。

###將ueditor中的圖片模塊的在線管理功能和七牛結合

第一步,更改ueditor.config.js,找到imageManagerUrl,雖然和ueditor裏面的裏面在線管理jsp的名字同樣,不過請注意他的路徑。imageManagerPath則是一個圖片修正路徑,和以前圖片上傳的修正路徑對應。

//圖片在線管理配置區
    ,imageManagerUrl: "imageManager.jsp"       //圖片在線管理的處理地址
    ,imageManagerPath:"http://duoduo.u.qiniudn.com/"

而後是imageManager.jsp,通過ueditor裏面imageManager.jsp和Uploader.java兩個文件的研究發現,imageManager.jsp其實是會返回一個/圖片aue_separate_ue/圖片bue_separate_ue/圖片cue_separate_ue的字符串,而後image.js會將這個串根據ue_separate_ue切割,而且在前面加上imageManagerPath組成最終的一個圖片列表。搞明白機制以後不難根據七牛的sdk寫出以下的代碼。

<%@ page language="java" pageEncoding="utf-8"%>
<%@ page import="java.util.*,com.qiniu.*"%>
<%@ page import="java.io.*"%>
<%@ page import="javax.servlet.ServletContext"%>
<%@ page import="javax.servlet.http.HttpServletRequest"%>
<%
	Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
	RSFClient client = new RSFClient(mac);
	ListPrefixRet list = client.listPrifix("duoduo", "", "", 10);
	StringBuffer sb = new StringBuffer();
	for (ListItem item : list.results) {
		sb.append("/");
		sb.append(item.key);
		sb.append("ue_separate_ue");
	}
	String imgStr = sb.toString();
	if (imgStr != "") {
		imgStr = imgStr
				.substring(0, imgStr.lastIndexOf("ue_separate_ue"))
				.replace(File.separator, "/").trim();
	}
	out.print(imgStr);
%>

至此,ueditor和七牛雲存儲圖片功能的所有整合就結束了。圖片上傳的配置主要在image.html裏面。

相關文章
相關標籤/搜索