關於富文本編輯器—UEditor(java版)的使用,以及如何將UEditor的文件/圖片上傳路徑改爲絕對路徑

忽然發現很久沒寫博客了,感受變懶了,是要讓本身養成常常寫文章的習慣才行。既能夠分享本身的所學,和所想,和你們一塊兒討論,發現本身的不足的問題。javascript

你們可能常常會用到富文本編輯器,今天我要說的是UEditor的使用,這是一個簡單易用的開源富文本編輯器。可是對於沒有用過的同窗而言仍是須要稍微瞭解一下的。php

可能有些人也知道,UEditor是百度的開源富文本編輯器,固然也有一些其餘優秀的富文本編輯器,好比kindeditor,ckeditor之類的,你們能夠對比一下使用,可是我今天主要是講java版的UEditor。html

你們能夠經過 https://ueditor.baidu.com/website/download.html 選擇本身想使用的版本下載。java

首先介紹一下它的目錄層級:nginx

                   

  • dialogs: 彈出對話框對應的資源和JS文件
  • jsp或php或asp或net: 涉及到服務器端操做的後臺文件
  • lang: 編輯器國際化顯示的文件
  • themes: 樣式圖片和樣式文件
  • third-party: 第三方插件(包括代碼高亮,源碼編輯等組件)
  • ueditor.all.js: 開發版代碼合併的結果,目錄下全部文件的打包文件
  • ueditor.all.min.js: ueditor.all.js文件的壓縮版,建議在正式部署時採用
  • ueditor.config.js: 編輯器的配置文件,建議和編輯器實例化頁面置於同一目錄
  • ueditor.parse.js: 編輯的內容顯示頁面引用,會自動加載表格、列表、代碼高亮等樣式

咱們把UEditor拷貝到咱們的項目路徑下,與你的頁面是在同一個目錄下就能夠了。web

在須要用到UEditor的頁面引入下面的文件便可,根據本身的實際路徑引入:面試

    <script type="text/javascript" charset="utf-8" src="../../ueditor/ueditor.config.js"></script>
    <script type="text/javascript" charset="utf-8" src="../../ueditor/ueditor.all.min.js"></script>
    <script type="text/javascript" src="../../ueditor/lang/zh-cn/zh-cn.js"></script>  

在頁面須要展現富文本編輯器的位置這樣引入:json

 1           <!-- 加載編輯器的容器 -->
 2                 <div class="k-field" style="width:1024px;">
 3                     <script id="article_content" name="article_content" type="text/plain" style="width:1024px;height:400px;">
 4                         在這裏輸入您的內容......
 5                     </script>
 6                 </div>
 7                 <!-- 實例化編輯器 -->
 8                 <script type="text/javascript">
 9                     var ue = UE.getEditor('article_content',{ 10 <!-- 根據我的須要配置,不配置則按默認的 --> 11  maximumWords:50000, 12  enableAutoSave:true, 13  saveInterval:500 14  }); 15 </script> 

 

除此以外咱們還要引入UEditor所須要的jar包 在 UEditor目錄下的  jsp/lib 下有,若是你有引入這些包的話,則無需引入。服務器

若是你的不是maven項目的話,直接把全部包拷貝到項目下面的lib目錄下就能夠自動引入了,可是若是是maven項目的話,maven庫裏沒有ueditor的包,那就不能按照日常的方式引入了,能夠把ueditor的包拷貝到項目的lib目錄下以後,在pom.xml中這樣引入:app

1         <dependency>
2             <groupId>com.baidu.ueditor</groupId>
3             <artifactId>ueditor</artifactId>
4             <version>1.1.2</version>
5             <scope>system</scope>
6             <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/ueditor-1.1.2.jar</systemPath>
7         </dependency>

 

上面的步驟都完成以後就能夠去對應的頁面試一下效果如何。若是沒有作任何改動的話就是下面的效果:

 

以上就完成了最簡單的UEditor富文本編輯器引入方式,能夠體驗一下上傳圖片和文件,均可以正常上傳。

可是當你從新部署項目以後會發現,怎麼以前上傳的文件和圖片下載不了也看不到了呢。這就是由於UEditor原生上傳文件和圖片的方式是上傳到項目路徑下,那從新部署項目,那不就把原來上傳的文件和圖片覆蓋了咯。

因此爲了不這樣的狀況發生,咱們接下來稍微修改一下UEditor的代碼。可能步驟有點多,可是耐心地跟着個人步驟一步步去理解,應該能夠很快就知道怎麼修改。

經過查看源碼,下面咱們一步步來追蹤:

1. 上傳圖片或文件時最開始會進入「ueditor/jsp/controller.jsp」,咱們查看其代碼:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     import="com.baidu.ueditor.ActionEnter"
 3     pageEncoding="UTF-8"%>
 4 <%@ page trimDirectiveWhitespaces="true" %>
 5 <%
 6 
 7     request.setCharacterEncoding( "utf-8" );
 8     response.setHeader("Content-Type" , "text/html"); 9 String rootPath = application.getRealPath( "/" ); 10 out.write( new ActionEnter( request, rootPath ).exec() ); 11 12 %>
第9行中的rootPath 是獲取 項目的實際路徑,並做爲 ActionEnter 構造函數的參數之一實例化對象,在這個構造函數中(以下面的代碼)會去初始化改類的成員變量以及經過「ConfigManager.getInstance」獲取配置,
實際上是獲取 ueditor/jsp/config.json 的配置信息。你們能夠去看一下里面配置了一些什麼內容,裏面也有註釋,我這裏粘貼圖片的配置內容:
1     public ActionEnter(HttpServletRequest request, String rootPath) {
2         this.request = request; 3 this.rootPath = rootPath; 4 this.actionType = request.getParameter("action"); 5 this.contextPath = request.getContextPath(); 6 this.configManager = ConfigManager.getInstance(this.rootPath, this.contextPath, request.getRequestURI()); 7 }
 1     /* 上傳圖片配置項 */
 2     "imageActionName": "uploadimage", /* 執行上傳圖片的action名稱 */
 3     "imageFieldName": "upfile", /* 提交的圖片表單名稱 */
 4     "imageMaxSize": 2048000, /* 上傳大小限制,單位B */
 5     "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上傳圖片格式顯示 */
 6     "imageCompressEnable": true, /* 是否壓縮圖片,默認是true */
 7     "imageCompressBorder": 1600, /* 圖片壓縮最長邊限制 */
 8     "imageInsertAlign": "none", /* 插入的圖片浮動方式 */
 9     "imageUrlPrefix": "", /* 圖片訪問路徑前綴 */
10     "imagePathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上傳保存路徑,能夠自定義保存路徑和文件名格式 */
11                                 /* {filename} 會替換成原文件名,配置這項須要注意中文亂碼問題 */
12                                 /* {rand:6} 會替換成隨機數,後面的數字是隨機數的位數 */
13                                 /* {time} 會替換成時間戳 */
14                                 /* {yyyy} 會替換成四位年份 */
15                                 /* {yy} 會替換成兩位年份 */
16                                 /* {mm} 會替換成兩位月份 */
17                                 /* {dd} 會替換成兩位日期 */
18                                 /* {hh} 會替換成兩位小時 */
19                                 /* {ii} 會替換成兩位分鐘 */
20                                 /* {ss} 會替換成兩位秒 */
21                                 /* 非法字符 \ : * ? " < > | */
22                                 /* 具請體看線上文檔: fex.baidu.com/ueditor/#use-format_upload_filename */

 

2. 總共也就幾行代碼,發現會調用 ActionEnter 類的 exec() 方法,我進入該方法:

1     public String exec() {
2         String callbackName = this.request.getParameter("callback"); 3 if (callbackName != null) { 4 return !this.validCallbackName(callbackName) ? (new BaseState(false, 401)).toJSONString() : callbackName + "(" + this.invoke() + ");"; 5 } else { 6 return this.invoke(); 7  } 8 }

3. 發現這個方法會調用 該類的 invoke() 方法,咱們繼續看invoke() 方法:

 1     public String invoke() {
 2         if (this.actionType != null && ActionMap.mapping.containsKey(this.actionType)) { 3 if (this.configManager != null && this.configManager.valid()) { 4 State state = null; 5 int actionCode = ActionMap.getType(this.actionType); 6 Map<String, Object> conf = null; 7 switch(actionCode) { 8 case 0: 9 return this.configManager.getAllConfig().toString(); 10 case 1: 11 case 2: 12 case 3: 13 case 4: 14 conf = this.configManager.getConfig(actionCode); 15 state = (new Uploader(this.request, conf)).doExec(); 16 break; 17 case 5: 18 conf = this.configManager.getConfig(actionCode); 19 String[] list = this.request.getParameterValues((String)conf.get("fieldName")); 20 state = (new ImageHunter(conf)).capture(list); 21 break; 22 case 6: 23 case 7: 24 conf = this.configManager.getConfig(actionCode); 25 int start = this.getStartIndex(); 26 state = (new FileManager(conf)).listFile(start); 27  } 28 29 return state.toJSONString(); 30 } else { 31 return (new BaseState(false, 102)).toJSONString(); 32  } 33 } else { 34 return (new BaseState(false, 101)).toJSONString(); 35  } 36 }

在上面的這個方法中咱們發現,在第7行代碼中有一個switch,根據 「actionCode」 的值的不一樣作一些不一樣的事情,咱們看一下這個值從哪裏來的,發現這個值是 經過調用這 個 方法 而獲得 「ActionMap.getType(this.actionType)」,咱們進去getType方法會發現 只是返回一個map的velue值,這個value值就是上的 mapping 裏的值,咱們經過第1步的配置文件能夠知道上傳圖片的是「uploadimage」

因此返回的value值是 1,而文件「uploadfile」返回的是4。咱們再看到上面的switch 能夠知道執行this.configManager.getConfig 從新組裝了配置信息並將配置信息做爲參數實例化Uploader ,並調用該實例 的 doExec()方法。

 1 public final class ActionMap {
 2     public static final Map<String, Integer> mapping = new HashMap<String, Integer>() { 3  { 4 this.put("config", Integer.valueOf(0)); 5 this.put("uploadimage", Integer.valueOf(1)); 6 this.put("uploadscrawl", Integer.valueOf(2)); 7 this.put("uploadvideo", Integer.valueOf(3)); 8 this.put("uploadfile", Integer.valueOf(4)); 9 this.put("catchimage", Integer.valueOf(5)); 10 this.put("listfile", Integer.valueOf(6)); 11 this.put("listimage", Integer.valueOf(7)); 12  } 13  }; 14 public static final int CONFIG = 0; 15 public static final int UPLOAD_IMAGE = 1; 16 public static final int UPLOAD_SCRAWL = 2; 17 public static final int UPLOAD_VIDEO = 3; 18 public static final int UPLOAD_FILE = 4; 19 public static final int CATCH_IMAGE = 5; 20 public static final int LIST_FILE = 6; 21 public static final int LIST_IMAGE = 7; 22 23 public ActionMap() { 24  } 25 26 public static int getType(String key) { 27 return ((Integer)mapping.get(key)).intValue(); 28  } 29 }

4.我進入到 Uploader 類,上一步最後就是調用第10行的方法,由於配置裏 不是base64 因此執行else裏的內容,調用 BinaryUploader 的save方法

 1 public class Uploader {
 2     private HttpServletRequest request = null; 3 private Map<String, Object> conf = null; 4 5 public Uploader(HttpServletRequest request, Map<String, Object> conf) { 6 this.request = request; 7 this.conf = conf; 8  } 9 10 public final State doExec() { 11 String filedName = (String)this.conf.get("fieldName"); 12 State state = null; 13 if ("true".equals(this.conf.get("isBase64"))) { 14 state = Base64Uploader.save(this.request.getParameter(filedName), this.conf); 15 } else { 16 state = BinaryUploader.save(this.request, this.conf); 17  } 18 19 return state; 20  } 21 }

 

5. 咱們繼續進入到BinaryUploader 的save方法 ,咱們看到下面的代碼的第33行,會去設定 「physicalPath 」 的值,並做爲參數 調用 方法: StorageManager.saveFileByInputStream 進行保存,而「physicalPath 」 值是由 配置信息 參數 config 獲取。因此咱們須要經過修改配置 來 修改這個值就好了。

 

 1     public static final State save(HttpServletRequest request, Map<String, Object> conf) {
 2         FileItemStream fileStream = null; 3 boolean isAjaxUpload = request.getHeader("X_Requested_With") != null; 4 if (!ServletFileUpload.isMultipartContent(request)) { 5 return new BaseState(false, 5); 6 } else { 7 ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); 8 if (isAjaxUpload) { 9 upload.setHeaderEncoding("UTF-8"); 10  } 11 12 try { 13 for(FileItemIterator iterator = upload.getItemIterator(request); iterator.hasNext(); fileStream = null) { 14 fileStream = iterator.next(); 15 if (!fileStream.isFormField()) { 16 break; 17  } 18  } 19 20 if (fileStream == null) { 21 return new BaseState(false, 7); 22 } else { 23 String savePath = (String)conf.get("savePath"); 24 String originFileName = fileStream.getName(); 25 String suffix = FileType.getSuffixByFilename(originFileName); 26 originFileName = originFileName.substring(0, originFileName.length() - suffix.length()); 27 savePath = savePath + suffix; 28 long maxSize = ((Long)conf.get("maxSize")).longValue(); 29 if (!validType(suffix, (String[])conf.get("allowFiles"))) { 30 return new BaseState(false, 8); 31 } else { 32 savePath = PathFormat.parse(savePath, originFileName); 33 String physicalPath = (String)conf.get("rootPath") + savePath; 34 InputStream is = fileStream.openStream(); 35 State storageState = StorageManager.saveFileByInputStream(is, physicalPath, maxSize); 36  is.close(); 37 if (storageState.isSuccess()) { 38 storageState.putInfo("url", PathFormat.format(savePath)); 39 storageState.putInfo("type", suffix); 40 storageState.putInfo("original", originFileName + suffix); 41  } 42 43 return storageState; 44  } 45  } 46 } catch (FileUploadException var14) { 47 return new BaseState(false, 6); 48 } catch (IOException var15) { 49 return new BaseState(false, 4); 50  } 51  } 52 }

6.上面都是在分析代碼,下面就開始修改了,咱們在配置文件「ueditor/jsp/config.json」裏添加 saveRootPath ,這就是存儲圖片或文件的絕對根路徑,修改 imageUrlPrefix 的值,這個連接是要指向 絕對根路徑,用於訪問圖片或文件,你們能夠搭一個nginx服務器,或者直接用Tomcat也能夠,只要能訪問都行。

  "saveRootPath": "/data/", /* 文件和圖片上傳絕對根路徑*/
    /* 上傳圖片配置項 */
    "imageActionName": "uploadimage", /* 執行上傳圖片的action名稱 */
    "imageFieldName": "upfile", /* 提交的圖片表單名稱 */
    "imageMaxSize": 2048000, /* 上傳大小限制,單位B */
    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上傳圖片格式顯示 */
    "imageCompressEnable": true, /* 是否壓縮圖片,默認是true */
    "imageCompressBorder": 1600, /* 圖片壓縮最長邊限制 */
    "imageInsertAlign": "none", /* 插入的圖片浮動方式 */
    "imageUrlPrefix": "http://xxx", /* 指向saveRootPath的url,用於訪問圖片或文件*/
  "imagePathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}",

 

7. 咱們在 第 3 步 的invoke() 方法 中調用的  this.configManager.getConfig(actionCode); 方法裏 組裝絕對根路徑。就是在返回conf以前添加 下面代碼中的紅色內容。

1         conf.put("savePath", savePath);
2         conf.put("rootPath", this.rootPath); 3 conf.put("saveRootPath",this.jsonConfig.getString("saveRootPath")); 4 return conf;

8.  最後咱們把 第5步 裏的 save 方法裏的 physicalPath 值修改一下 ,註釋原來的內容,新增下面代碼的紅色內容。

1 //                      String physicalPath = (String)conf.get("rootPath") + savePath;
2                         String physicalPath = (String)conf.get("saveRootPath") + savePath;

這樣 咱們就把 原來的相對路徑改爲了咱們想要的絕對路徑了,你們能夠嘗試一下。

好了時間不早了,要休息了,你們若是有什麼更好的方法,能夠在評論去留言,你們一塊兒討論!若是有什麼不妥之處也請你們多多指教!

 

相關文章
相關標籤/搜索