最近在作一個新聞發佈平臺,放棄了很早的FCKEditor,使用CKEditor和CKFinder,儘管免費的CKFinder是Demo版本,可是功能完整,並且用戶都是比較集中精神發新聞的人,不會在乎這個。按照官網的document一步一步配置,雖然並不難,可是有些東西特別分散,仍是全英文的,因此我就整理了一下安裝過程和配置,以及須要注意的一些問題。但願對你們有所幫助。javascript
CKEditor: 在 http://ckeditor.com/download 頁面左側,能夠下載到各類版本的CKEditor,包括完整版full、標準版standard、基礎版basic等。在頁面右側上方,還有可定製的下載,能夠選擇Toolbar類型、插件、語言等。這裏咱們選擇4.1版本的Full版本,下載後獲得CKEditor_4.1_full.zip 。php
CKEditor for java: 在http://ckeditor.com/download 頁面右側下部,能夠下載到用於服務器端的工具,記得選擇for java版本。這裏選擇3.6.4版本。可是下載下來倒是 ckeditor-java-core-3.5.3.jar。不知道爲何。html
CKFinder: 在 http://cksource.com/ckfinder/trial 頁面,能夠下載到各類版本的CKFinder。仍然選擇java版。這裏咱們下載的是2.3.1版本,下載後獲得CKFinder_java_2.3.1.zip。java
解壓CKEditor_4.1_full.zip,把解壓獲得的目錄 ckeditor 徹底複製到網站根目錄下,也就是和WEB-INF同級。能夠給這個目錄加上版本號,即ckeditor4.1。web
把 ckeditor4.1/samples 徹底刪掉,把 ckeditor4.1/lang 裏面除了en.js和zh-cn.js以外的文件刪掉,把 ckeditor4.1 下的README.md, CHANGES.md刪掉。api
把 ckeditor-java-core-3.5.3.jar 放到yourapp/WEB-INF/lib下瀏覽器
解壓CKFinder_java_2.3.1.zip,獲得ckfinder目錄。將 ckfinder/CKFinderJava/ckfinder 目錄徹底複製到網站根目錄下,也就是和WEB-INF同級。能夠給這個目錄加上版本號,即ckfinder2.3.1。安全
把 ckfinder2.3.1/_samples徹底刪掉,把 ckfinder2.3.1/lang 下除了en.js和zh-cn.js以外的文件刪掉,把 ckfinder2.3.1 下的changelog.txt,install.txt,license.txt,translations.txt刪掉。服務器
把 ckfinder/CKFinderJava/WEB-INF/lib 下全部的jar包複製到yourapp/WEB-INF/lib下。app
把 ckfinder/CKFinderJava/WEB-INF/config.xml複製到yourapp/WEB-INF下,並更名爲ckfinder.xml。
Step1:找到須要放置CKEditor編輯器的頁面,引入CKEditor的js文件(${contextPath}是JSTL寫法,請改爲你本身的路徑寫法,絕對路徑或者相對路徑)
<script type="text/javascript" src="${contextPath}/ckeditor4.1/ckeditor.js"></script>
Step2:在須要提交的form裏,寫一個<textarea>
<form id="detailForm" method="post"> <textarea id="content" name="content"></textarea> <input type="button" value="保存" id="save" onclick="save()" /></form>
Step3:建立CKEditor實例
<script type="text/javascript"> var editor = null; window.onload = function(){ editor = CKEDITOR.replace('content'); //參數‘content’是textarea元素的name屬性值,而非id屬性值 }</script>
注意上面代碼中editor=CKEDITOR.repalce()必須寫在window.onload事件裏,或者寫在textarea元素後面,以避免出現content不存在的錯誤。上述代碼並非建立CKEditor實例的惟一方法,你們能夠自行查閱資料。
Step4:在頁面js中爲CKEditor編輯器設置/獲取值
editor.setData('這裏是須要傳遞給CKEditor編輯器實例的值'); editor.getData();
注意,上面代碼中用到了一個變量editor,就是Step3中定義的那個editor。這也就是爲何Step3裏面要單獨寫var editor = null這句代碼。固然,在<textarea></textarea>中直接設置值也能夠,可是那隻能在CKEDITOR.replace()以前起做用。
Step5:在後臺java代碼中獲取CKEditor編輯器的值
<script type="text/javascript"> function save(){ editor.updateElement(); //很是重要的一句代碼 //前臺驗證工做 //提交到後臺 }</script>
由於CKEditor編輯器取代了原來咱們寫的textarea元素,因此咱們在編輯器裏寫的內容,其實都不在textarea中,所以,爲了能在後臺經過textarea得到值,必須用editor.updateElement()來更新textarea元素。這樣,在後臺java代碼中就能夠用request.getParameter('content');或者其餘代碼獲得編輯器的內容了,不然獲得的極可能不是編輯器裏的內容。
方式一:修改ckeditor4.1/config.js文件
CKEDITOR.editorConfig = function( config ) { config.language = 'zh-cn'; config.uiColor = '#AADC6E'; };
方式二:複製ckeditor4.1/config.js,仍然放在ckeditor4.1目錄下,可是更名爲myconfig.js,並在這個文件中修改配置。可是要在建立編輯器實例時指明配置文件路徑:
<script type="text/javascript"> editor = = = CKEDITOR.replace( 'content'
方式三:在建立編輯器實例時指定配置
<script type="text/javascript"> var editor = null; window.onload = function() { editor = CKEDITOR.replace( 'content', uiColor: '#9AB8F3', language:'zh-cn' }); };</script>
使用第二種或者第三種方式的好處就在於,當你更新CKEditor版本時,不至於由於直接複製了新的config.js而覆蓋掉個性配置。
完整的CKEditor的配置選項在 這裏。下面是一些經常使用的配置。
language,defaultLanguage,contentLanguage, uiColor
autoGrow_maxHeight, autoGrow_minHeight, resize_maxHeight, resize_minHeight, resize_maxWidth, resize_minWidth
toolbarCanCollapse, toolbarGroups
forcePasteAsPlainText, pasteFromWordKeepsStructure, pasteFromWordRemoveFontStyles, pasteFromWordRemoveStyles
font_names, fontSize_sizes
在CKEditor編輯器裏面敲回車,默認是加一個<p></p>元素,並且在<p>以前和</p>以後會加換行。這就形成一個問題,保存的數據最後可能會出現「\t\n」。當咱們使用editor.setData(......)時,實際上變成了
editor.setData(...... );
由於數據自己帶有一個\t\n,使得js代碼換行了,從而頁面出錯。可能還有其餘方法解決這個問題,可是我採用的是禁止在回車變<p></p>時在後面添加換行。其方法是:
<script type="text/javascript"> var editor = null; window.onload = function() { editor = CKEDITOR.replace( 'content', { customConfig:'${contextPath}/ckeditor4.1/myconfig.js', on: { instanceReady: function( ev ) { this.dataProcessor.writer.setRules( 'p', { indent: false, breakBeforeOpen: false, //<p>以前不加換行 breakAfterOpen: false, //<p>以後不加換行 breakBeforeClose: false, //</p>以前不加換行 breakAfterClose: false //</p>以後不加換行7 }); } } }); };</script>
關於這部份內容,更多內容參看 http://docs.ckeditor.com/#!/guide/dev_output_format
沒有CKFinder,CKEditor做爲一個編輯器,也是能夠正常使用的,可是沒法在編輯器裏瀏覽服務器上的用戶上傳文件。因此要整合CKFinder。
Step1:在頁面中引入CKFinder的js文件
<script type="text/javascript" src="${contextPath}/ckfinder2.3.1/ckfinder.js"></script>
Step2:建立CKFinder實例
<script type="text/javascript"> var editor = null; window.onload = function() { editor = CKEDITOR.replace( 'content', { customConfig:'${contextPath}/ckeditor4.1/jwc_config.js' }); CKFinder.setupCKEditor( editor, '${contextPath}/ckfinder2.3.1/' ); };</script>
上面標紅的代碼,第一個參數是CKEditor實例,第二個參數是ckfinder的目錄(最好寫絕對路徑),注意最後要帶斜槓'/'。
Step3:在CKEditor裏配置經過哪一個頁面或者程序來瀏覽和上傳文件
找到你的項目裏配置CKEditor的位置(參看本文CKEditor的三種配置方式部分),配置如下內容:
CKEDITOR.editorConfig = = '/ckfinder2.3.1/ckfinder.html'= '/ckfinder2.3.1/ckfinder.html?type=Images'= '/ckfinder2.3.1/ckfinder.html?type=Flash'= '/ckfinder2.3.1/core/connector/java/connector.java?command=QuickUpload&type=Files'= '/ckfinder2.3.1/core/connector/java/connector.java?command=QuickUpload&type=Images'= '/ckfinder2.3.1/core/connector/java/connector.java?command=QuickUpload&type=Flash'
上面的六行代碼,指定了經過ckfinder2.3.1/ckfinder.html來瀏覽圖片或者其餘文件,經過/ckfinder2.3.1/core/connector/java/connector.java來上傳文件。
找到yourapp/WEB-INF/ckfinder.xml,編輯其中的內容。下面簡要介紹一下每一項的含義,其餘未介紹的內容請參照ckfinder.xml自己的註釋以及 這裏。
enabled:true表示開啓ckfinder功能。默認是false。
baseDir:上傳文件存放的路徑,這裏必須寫從物理地址的全路徑,好比C:\myapp\uploadfiles\。不能寫相對路徑,並且最後必定要加斜槓「/」。這一項能夠不配置,留空的話,系統會自動根據baseURL去找到baseDir。可是建議仍是配置上比較好。
baseURL:上傳文件存放的URL,這裏能夠寫一個相對路徑或者一個完整的URL,好比"http://www.example.com/uploadfiles/" 或者 "/uploadfiles/"。注意,必定要在最後加一個斜槓「/」。更多解釋參看這裏。
types:指定上傳文件的類型。它的子元素是<type name=""></type>,其中的name要和上面CKEditor裏配置的路徑的type一致。好比上面配置了filebrowserImageBrowseUrl = 'ckfinder2.3.1/ckfinder.html?type=Images',那麼就要配一個<type name="Images"></type>。在<type></type>元素裏,能夠配置該類型文件存放的子目錄(放在baseDir下)、子URL、文件最大字節數、容許上傳的文件擴展名、禁止上傳的文件擴展名。
disallowUnsafeCharacters:設置爲false。若是設置爲true,在建立文件夾或者上傳文件時,名字裏不能包含不安全的字符。這隻在IIS裏生效。
checkDoubleExtension:檢查多級擴展名,或許你禁止用戶上傳php文件,容許用戶上傳rar文件。若是此項設置爲false,文件foo.php.rar就會上傳到服務器,這不安全。所以此項設置爲true。
secureImageUploads:設置此項爲true,能夠檢查文件究竟是不是圖片,頗有可能有人把一個可執行文件加了後綴變成了.jpg,但實際上它不是一個圖片文件。
找到yourapp/WEB-INF/web.xml,添加如下內容:
<servlet> <servlet-name>ConnectorServlet</servlet-name> <servlet-class>com.ckfinder.connector.ConnectorServlet</servlet-class> <init-param> <param-name>XMLConfig</param-name> <param-value>/WEB-INF/ckfinder.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ConnectorServlet</servlet-name> <url-pattern> /ckfinder2.3.1/core/connector/java/connector.java </url-pattern> </servlet-mapping>
上面配置裏第一個init-param是指定CKFinder的配置文件位置。也就是上面第8部分提到的那個配置文件。
目前來講,CKFinder可以正常地使用了。可是,即使沒有你的項目的管理權限,在瀏覽器中輸入yoursite/ckfinder2.3.1/ckfinder.html,也同樣能看到你的服務器上存放的那些文件,他們甚至能夠上傳和刪除文件。有兩個地方能夠增強CKFinder的安全性。
<userRoleSessionVar>CKFinder_UserRole</userRoleSessionVar><accessControls> <accessControl> <role>admin</role> <resourceType>*</resourceType> <folder>/</folder> <folderView>true</folderView> <folderCreate>true</folderCreate> <folderRename>true</folderRename> <folderDelete>false</folderDelete> <fileView>true</fileView> <fileUpload>true</fileUpload> <fileRename>true</fileRename> <fileDelete>false</fileDelete> </accessControl></accessControls>
而後在java代碼中合適的位置,好比login()方法裏,添加如下代碼
request.getSession().setAttribute("CKFinder_UserRole", "admin");
系統會在訪問yoursite/ckfinder2.3.1/ckfinder.html時(包括點擊下圖的「瀏覽服務器」按鈕),檢查CKFinder_UserRole的值是什麼,它具備的權限是什麼。若是一我的沒有登陸系統,而是直接訪問yoursite/ckfinder2.3.1/ckfinder.html,那麼系統就會檢查到CKFinder_UserRole是null,他就看不到服務器上的文件。
在yourapp/WEB-INF/web.xml裏,修改關於ckfinder的配置,增長一段代碼:
<servlet> <servlet-name>ConnectorServlet</servlet-name> <servlet-class>com.ckfinder.connector.ConnectorServlet</servlet-class> <init-param> <param-name>configuration</param-name> <param-value>mypackage.CKFinderConfiguration</param-value> </init-param> <init-param> <param-name>XMLConfig</param-name> <param-value>/WEB-INF/ckfinder.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ConnectorServlet</servlet-name> <url-pattern> /ckfinder2.3.1/core/connector/java/connector.java </url-pattern> </servlet-mapping>
在包路徑mypackage下建立一個類CKFinderConfiguration(包路徑和類名按照本身的項目代碼組織狀況來取名),代碼以下:
CKFinderConfiguration CKFinderConfiguration( checkAuthentication(= request.getSession().getAttribute("userid" logined = !userid.equals(""
關鍵在於checkAuthentication()方法。能夠在checkAuthentication()方法裏編寫關於用戶認證的一些判斷,好比用戶是否登陸系統,用戶是否有權限管理上傳文件。若是符合條件,就返回ture,不然返回false。
兩種方法均可以讓ckfinder更安全,固然同時使用會更好。可是注意二者區別,後者只能在比較粗的粒度進行控制。