我們?cè)谏掀恼轮袑W(xué)習(xí)了 上傳圖片的配置: 百度ueditor富文本--配置圖片上傳
在文章的最后 講到 ueditor 默認(rèn)設(shè)置的 保存圖片的 路徑 是相對(duì)路徑,項(xiàng)目相關(guān)的。
保存的圖片會(huì)放在tomcat的webapp目錄下的 項(xiàng)目 文件夾中。 F:\tomcat7\webapps\ROOT 這樣的配置 會(huì) 導(dǎo)致 重啟 tomcat后 保存的 圖片 丟失。
解決方法一 修改圖片保存路徑在tomcat的webapp中項(xiàng)目之外
修改了config.json中的imagePathFormat參數(shù)重新設(shè)置圖片保存路徑,比如: "imagePathFormat": "/../temp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */
我們這里在原路徑上加了/../temp。 意思是 項(xiàng)目路徑ROOT里的的上一級(jí)路徑,也就是 路徑設(shè)置為項(xiàng)目之外,webapp中。 如圖: 
F:\tomcat7\webapps\temp\ueditor\jsp\upload\image\20170825

需要注意的是: 一、圖片保存路徑在項(xiàng)目之外最好先新建好文件夾,不然第一次上傳圖片時(shí)創(chuàng)建目錄速度會(huì)比較慢,會(huì)導(dǎo)致首張圖片回調(diào)找不到圖片404。 
圖片保存的路徑最好在tomcat的webapp文件夾中,這樣我們才能訪(fǎng)問(wèn)到圖片。 如果圖片不在Webapp目錄下的,需要做做映射才能訪(fǎng)問(wèn)圖片,回調(diào)顯示圖片才能成功。 UEditor后端保存圖片到目標(biāo)位置之后,返回前端一個(gè)url。前端根據(jù)url,去取圖片,取不到。 如果想把圖片存儲(chǔ)到 非Webapp等硬盤(pán)目錄,比如C:/img,需要手動(dòng)修改controller.jsp的rootPath
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- import="com.baidu.ueditor.ActionEnter"
- pageEncoding="UTF-8"%>
- <%@ page trimDirectiveWhitespaces="true" %>
- <%
-
- request.setCharacterEncoding( "utf-8" );
- response.setHeader("Content-Type" , "text/html");
-
- //String rootPath = application.getRealPath( "/" );
- String rootPath = "c:/img";
- System.out.print(rootPath);
- out.write( new ActionEnter( request, rootPath ).exec() );
-
- %>
圖片保存在項(xiàng)目的外面,比如C:/img,前端請(qǐng)求不可能直接訪(fǎng)問(wèn)到,需要做映射。linux系統(tǒng)的話(huà) 一般需要做靜態(tài)資源服務(wù)器域名訪(fǎng)問(wèn)。
解決方法二 把圖片上傳到遠(yuǎn)程服務(wù)器上
在良好的web架構(gòu)中,圖片和web站點(diǎn)是分開(kāi)的,放在不同的服務(wù)器上,實(shí)現(xiàn)靜態(tài)資源分離。
也就是說(shuō) 我們的web 在使用ueditor富文本編輯器時(shí) 上傳插件上傳的圖片也應(yīng)該上傳到 圖片資源服務(wù)器中。
也就是要 上傳到遠(yuǎn)程服務(wù)器上, 甚至可能要實(shí)現(xiàn)跨域上傳。
查詢(xún)了很多資料之后 發(fā)現(xiàn) 主要有兩種實(shí)現(xiàn)方式:
推薦方式二,方式一實(shí)現(xiàn)起來(lái)比較復(fù)雜,需要一定的理解。
方式一 重寫(xiě)接收?qǐng)D片的controller以及上傳組件的調(diào)用
默認(rèn)使用的controller.jsp是一種很簡(jiǎn)單的操作,就是把文件流保存到 指定路徑下。
如果我們要實(shí)現(xiàn) 跨域上傳圖片到遠(yuǎn)程服務(wù)器的話(huà) 必須重寫(xiě) 這個(gè)controller,接收文件流之后 上傳到遠(yuǎn)程服務(wù)器 ,返回圖片地址。
關(guān)于接收文件流 上傳到遠(yuǎn)程服務(wù)器的 代碼思路 可以參考:
java上傳文件到遠(yuǎn)程服務(wù)器(一)---HttpURLConnection方式
java上傳文件到遠(yuǎn)程服務(wù)器(二)---HttpClient方式
java上傳文件到遠(yuǎn)程服務(wù)器七牛云
JSP頁(yè)面修改JSP頁(yè)面中在初始化UE的JS中 需要重新設(shè)置一下每個(gè)插件的調(diào)用事件,如下: - // 初始化文本編輯器
- $(".ueditorFlag").each(function() {
- var id = this.id;
- var ue = UE.getEditor(id, {
- pasteplain: true, /* 純文本粘貼 */
- autoHeightEnabled:false,/* 啟用右側(cè)滾輪,默認(rèn)是true自動(dòng)長(zhǎng)高模式*/
- toolbars: [[
- 'fullscreen', 'source', '|', 'undo', 'redo', '|',
- 'bold', 'italic', 'underline',
- 'removeformat', '|',
- 'insertorderedlist', 'insertunorderedlist',
- 'indent', '|', 'justifyleft', 'justifycenter',
- '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', 'insertimage',
- '|', 'link', 'unlink'
- ]]
- });
-
- UE.Editor.prototype._bkGetActionUrl=UE.Editor.prototype.getActionUrl;
- UE.Editor.prototype.getActionUrl=function(action){
- if (action == 'uploadimage' ||action== 'uploadscrawl' || action == 'uploadimage') {
- return "${basePath}/upload";
- } else if(action =='uploadvideo') {
- return "${basePath}/upload";
- } else if(action == 'listimage'){
- return "${basePath}/download";
- } else{
- return this._bkGetActionUrl.call(this, action);
- }
- }
-
- console.log('ueditor for ' + id + ' init.');
- });
簡(jiǎn)單介紹: UE.Editor.prototype._bkGetActionUrl=UE.Editor.prototype.getActionUrl; 是用來(lái)獲取Action的,照寫(xiě)就行,然后就是下面的 UE.Editor.prototype.getActionUrl=function(action){....} 這里面的if語(yǔ)句,就是用來(lái)設(shè)置自定義action路由的,這里叫Controller。這里的action也就是 我們選中的 插件的 動(dòng)作,對(duì)應(yīng)的名稱(chēng)可以在 config.json中查找。 如圖: 
新建一個(gè)接收?qǐng)D片上傳到遠(yuǎn)程服務(wù)器的controller- /**
- * 上傳圖片
- *
- * @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;//這個(gè)是UEditor需要的返回值內(nèi)容,UEditor要的返回值需要封裝成Json格式
- // 轉(zhuǎn)型為MultipartHttpRequest:
- MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest) request;
- // 獲得文件:
- MultipartFile file =multipartRequest.getFile("upfile"); //UEditor傳到后臺(tái)的是這個(gè)upfile,其他的文件上傳,應(yīng)該也差不多是這個(gè),還沒(méi)去研究,斷點(diǎn)一下就知道了
- // 寫(xiě)入文件
- File imageFile =newFile("/"+Uuid()+".jpg");
- file.transferTo(imageFile);
- //現(xiàn)在獲取了File接下來(lái)要上傳到OSS上
- if(imageFile!=null){
- rui = new ReturnUploadImage();
- rui.setTitle(imageFile.getName());//這里需要設(shè)置文件名稱(chēng)如:xxx.jpg
- rui.setOriginal(imageFile.getName());//這里需要設(shè)置文件名稱(chēng)如:xxx.jpg
- // 判斷文件是否為圖片文件
- String r =ImageUtils.fileDetermine(imageFile, 3 * 1024);
- if (!StringUtils.isNotEmpty(r)) {
- // 上傳文件(這里文件類(lèi)型,要根據(jù)實(shí)際上傳的類(lèi)型去做,暫時(shí)是直接設(shè)置了.jpg,并且先保存到磁盤(pán),這樣對(duì)磁盤(pán)比較傷,每次上傳都要先保存到磁盤(pán),然后再刪除)
- ResultInfo resultInfo = OSSObjTools.uploadObject(imageFile,
- "subWebPublicNotice");//這里是自己封裝的OSS,上傳到OSS上面
- // 判斷如果返回結(jié)果不為空并且MD5返回值比較結(jié)果正確,就設(shè)置文件路徑保存到數(shù)據(jù)庫(kù)
- if (resultInfo != null
- &&resultInfo.geteTag().equalsIgnoreCase(
- MD5Tools.file2MD5(imageFile))) {
- rui.setState("SUCCESS");//這里上傳成功的話(huà)一定要設(shè)置大寫(xiě)的 SUCCESS,失敗還沒(méi)測(cè)試,猜應(yīng)該是FAIL,回頭再去官網(wǎng)找找
- rui.setUrl(CommonTools.catchUrlPath(PubParam.BUCKET_NAME,
- PubParam.Mark_ShenZhen) +resultInfo.getFilePath());//這里是設(shè)置返回給UEditor的圖片地址
- }
- }
- // 判斷臨時(shí)存放的文件是否存在
- if (imageFile.exists()) {
- // 刪除臨時(shí)存放的文件
- imageFile.delete();
- }
- }
- String result = JSON.toJSONString(rui);//這邊就是為了返回給UEditor做的格式轉(zhuǎn)換
- response.getWriter().write(result);
- return null;
- }
大家可以在這個(gè)步驟上進(jìn)行 修改 使用 我們前面提供的三種方式 修改 圖片上傳。
上傳完成之后 返回圖片的地址 即可。
需要注意的是 這里返回的 圖片地址使用json格式,格式必須 符合 ueditor的格式規(guī)范,否則 插件無(wú)法識(shí)別 回顯圖片。
返回給UEditor的參數(shù) 這里你應(yīng)該參考http://fex.baidu.com/ueditor/#dev-request_specification 官方文檔里面的 后端請(qǐng)求參數(shù)-請(qǐng)求規(guī)范, 官方有介紹了,返回參數(shù)的格式,格式中json的key就是對(duì)應(yīng)了類(lèi)ReturnUploadImage里面的屬性。 轉(zhuǎn)換后格式應(yīng)該是這樣的,要嚴(yán)格按照文檔上面的格式 {"original":"5dfcfea3e3b442bda3972053266c3bd3.jpg","state":"SUCCESS","title":"5dfcfea3e3b442bda3972053266c3bd3.jpg","url":"http://www./mmmm/xxxModuleName/20150922/5dfcfea3e3b442bda3972053266c3bd3.jpg"} 注:不同的文件上傳,返回的屬性不一樣 =======================ReturnUploadImageStart============================================ public classReturnUploadImage { private String state;//上傳狀態(tài)SUCCESS 一定要大寫(xiě) private String url;//上傳地址 private String title;//圖片名稱(chēng)demo.jpg private String original;//圖片名稱(chēng)demo.jpg ....getter & setter... } =======================ReturnUploadImage End============================================== 這里官方文檔也說(shuō)的很清楚,對(duì)應(yīng) config、uploadimage、uploadscrawl、uploadvideo、uploadfile....都有各自的格式 文檔里面這些對(duì)應(yīng)的就是xxxxActionName 官方文檔截圖:

方式二 調(diào)用遠(yuǎn)程服務(wù)器上的controller.jsp
圖片上傳時(shí)調(diào)用的接口是在ueditor.config.js中設(shè)置的: - // 服務(wù)器統(tǒng)一請(qǐng)求接口路徑
- , serverUrl: URL + "jsp/controller.jsp"
我們就想著 能不能直接把這個(gè) 改成 遠(yuǎn)程服務(wù)器上的 controller.jsp就可以把圖片上傳到遠(yuǎn)程服務(wù)器上了。
答案是 可以。
但是 需要做一些處理。
環(huán)境布置
因?yàn)槲覀兪褂玫膉ava版本的ueditor,controller.jsp運(yùn)行接收?qǐng)D片是需要java環(huán)境的,所以我們首先在遠(yuǎn)程服務(wù)器上部署一個(gè)tomcat。 然后在tomcat的webapp目錄中新建一個(gè)ROOT目錄。 把config.json和controller.jsp放入其中。 啟動(dòng)tomcat即可。 如圖: 
config.json內(nèi)容如下: - /* 前后端通信相關(guān)的配置,注釋只允許使用多行方式 */
- {
- /* 服務(wù)器存儲(chǔ)配置 */
- "saveRootPath": "/data/nginx/static", /* 文件保存的根路徑 */
-
- /* 上傳圖片配置項(xiàng) */
- "imageActionName": "uploadimage", /* 執(zhí)行上傳圖片的action名稱(chēng) */
- "imageFieldName": "upfile", /* 提交的圖片表單名稱(chēng) */
- "imageMaxSize": 2048000, /* 上傳大小限制,單位B */
- "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上傳圖片格式顯示 */
- "imageCompressEnable": true, /* 是否壓縮圖片,默認(rèn)是true */
- "imageCompressBorder": 1600, /* 圖片壓縮最長(zhǎng)邊限制 */
- "imageInsertAlign": "none", /* 插入的圖片浮動(dòng)方式 */
- "imageUrlPrefix": "http://upload.", /* 圖片訪(fǎng)問(wèn)路徑前綴 */
- "imagePathFormat": "/editor/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */
- /* {filename} 會(huì)替換成原文件名,配置這項(xiàng)需要注意中文亂碼問(wèn)題 */
- /* {rand:6} 會(huì)替換成隨機(jī)數(shù),后面的數(shù)字是隨機(jī)數(shù)的位數(shù) */
- /* {time} 會(huì)替換成時(shí)間戳 */
- /* {yyyy} 會(huì)替換成四位年份 */
- /* {yy} 會(huì)替換成兩位年份 */
- /* {mm} 會(huì)替換成兩位月份 */
- /* {dd} 會(huì)替換成兩位日期 */
- /* {hh} 會(huì)替換成兩位小時(shí) */
- /* {ii} 會(huì)替換成兩位分鐘 */
- /* {ss} 會(huì)替換成兩位秒 */
- /* 非法字符 \ : * ? " < > | */
- /* 具請(qǐng)?bào)w看線(xiàn)上文檔: fex.baidu.com/ueditor/#use-format_upload_filename */
-
- /* 涂鴉圖片上傳配置項(xiàng) */
- "scrawlActionName": "uploadscrawl", /* 執(zhí)行上傳涂鴉的action名稱(chēng) */
- "scrawlFieldName": "upfile", /* 提交的圖片表單名稱(chēng) */
- "scrawlPathFormat": "/editor/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */
- "scrawlMaxSize": 2048000, /* 上傳大小限制,單位B */
- "scrawlUrlPrefix": "http://upload.", /* 圖片訪(fǎng)問(wèn)路徑前綴 */
- "scrawlInsertAlign": "none",
-
- /* 截圖工具上傳 */
- "snapscreenActionName": "uploadimage", /* 執(zhí)行上傳截圖的action名稱(chēng) */
- "snapscreenPathFormat": "/editor/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */
- "snapscreenUrlPrefix": "http://upload.", /* 圖片訪(fǎng)問(wèn)路徑前綴 */
- "snapscreenInsertAlign": "none", /* 插入的圖片浮動(dòng)方式 */
-
- /* 抓取遠(yuǎn)程圖片配置 */
- "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
- "catcherActionName": "catchimage", /* 執(zhí)行抓取遠(yuǎn)程圖片的action名稱(chēng) */
- "catcherFieldName": "source", /* 提交的圖片列表表單名稱(chēng) */
- "catcherPathFormat": "/editor/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */
- "catcherUrlPrefix": "http://upload.", /* 圖片訪(fǎng)問(wèn)路徑前綴 */
- "catcherMaxSize": 2048000, /* 上傳大小限制,單位B */
- "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取圖片格式顯示 */
-
- /* 上傳視頻配置 */
- "videoActionName": "uploadvideo", /* 執(zhí)行上傳視頻的action名稱(chēng) */
- "videoFieldName": "upfile", /* 提交的視頻表單名稱(chēng) */
- "videoPathFormat": "/editor/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */
- "videoUrlPrefix": "http://upload.", /* 視頻訪(fǎng)問(wèn)路徑前綴 */
- "videoMaxSize": 102400000, /* 上傳大小限制,單位B,默認(rèn)100MB */
- "videoAllowFiles": [
- ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
- ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上傳視頻格式顯示 */
-
- /* 上傳文件配置 */
- "fileActionName": "uploadfile", /* controller里,執(zhí)行上傳視頻的action名稱(chēng) */
- "fileFieldName": "upfile", /* 提交的文件表單名稱(chēng) */
- "filePathFormat": "/editor/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上傳保存路徑,可以自定義保存路徑和文件名格式 */
- "fileUrlPrefix": "http://upload.", /* 文件訪(fǎng)問(wèn)路徑前綴 */
- "fileMaxSize": 51200000, /* 上傳大小限制,單位B,默認(rèn)50MB */
- "fileAllowFiles": [
- ".png", ".jpg", ".jpeg", ".gif", ".bmp",
- ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
- ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
- ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
- ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
- ], /* 上傳文件格式顯示 */
-
- /* 列出指定目錄下的圖片 */
- "imageManagerActionName": "listimage", /* 執(zhí)行圖片管理的action名稱(chēng) */
- "imageManagerListPath": "/editor/upload/image/", /* 指定要列出圖片的目錄 */
- "imageManagerListSize": 20, /* 每次列出文件數(shù)量 */
- "imageManagerUrlPrefix": "http://upload.", /* 圖片訪(fǎng)問(wèn)路徑前綴 */
- "imageManagerInsertAlign": "none", /* 插入的圖片浮動(dòng)方式 */
- "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件類(lèi)型 */
-
- /* 列出指定目錄下的文件 */
- "fileManagerActionName": "listfile", /* 執(zhí)行文件管理的action名稱(chēng) */
- "fileManagerListPath": "/editor/upload/file/", /* 指定要列出文件的目錄 */
- "fileManagerUrlPrefix": "http://upload.", /* 文件訪(fǎng)問(wèn)路徑前綴 */
- "fileManagerListSize": 20, /* 每次列出文件數(shù)量 */
- "fileManagerAllowFiles": [
- ".png", ".jpg", ".jpeg", ".gif", ".bmp",
- ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
- ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
- ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
- ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
- ] /* 列出的文件類(lèi)型 */
-
- }
saveRootPath 和 imagePathFormat 共同決定了 存儲(chǔ)的路徑 /data/nginx/static/editor/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}。
controller.jsp代碼為: - <%@ page language="java" contentType="text/html; charset=UTF-8" import="com.baidu.ueditor.ActionEnter" pageEncoding="UTF-8"%>
- <%@ page trimDirectiveWhitespaces="true"%>
- <%
- request.setCharacterEncoding("utf-8");
- response.setHeader("Content-Type", "text/html");
- response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");
- response.setHeader("Access-Control-Allow-Headers", "X-Requested-With,X_Requested_With");
- String rootPath = application.getRealPath("/");
- out.write(new ActionEnter(request, rootPath).exec());
- %>
response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080"); response.setHeader("Access-Control-Allow-Headers", "X-Requested-With,X_Requested_With");
這兩句是相對(duì)于原controller.jsp新增的。 主要是允許跨域傳輸。
http://localhost:8080需要修改成與自己web服務(wù)器所在的 ip或者域名一致。
我這里是 用本地來(lái)測(cè)試 所以設(shè)置成了http://localhost:8080。
如果不加這兩句的話(huà) 會(huì)報(bào)跨域錯(cuò)誤,類(lèi)似于: XMLHttpRequest cannot load http:///controller.jsp?action=uploadimage&encode=utf-8. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://' is therefore not allowed access.
啟動(dòng)tomcat后我們發(fā)現(xiàn)已經(jīng)可以訪(fǎng)問(wèn)到 這個(gè)controller了。 我這里圖片資源服務(wù)器是配置有域名的,如果域名是: test.。 tomcat的端口是9003。 直接訪(fǎng)問(wèn)tomcat的端口顯示如下: 
如果沒(méi)有域名的話(huà) 直接使用遠(yuǎn)程ip也可以。
那么 我們就可以在web中配置這個(gè)服務(wù)器接收接口了。 找到 web項(xiàng)目初始化ueditor使用的ueditor.confi.js。 修改如下: - , serverUrl: "http://test.:9003/controller.jsp"
如圖:
到這里就配置完成了。
啟動(dòng)web項(xiàng)目,上傳圖片成功: 
然后到 配置的保存圖片路徑/data/nginx/static/editor/upload/image中查看,成功保存: 
|