在JSP裏使用CKEditor和CKFinder

在JSP裏使用CKEditor和CKFinder

爲了更新二手代碼中的fckeditor,研究了最新的ckeditor,因爲以前用的時候沒有用到java版的ckfinder,都是自己寫的servlet,所以重新整理一下。

1. 下載CKEditor相關的安裝文件

  • CKEditor: 在 http://ckeditor.com/download 頁面左側,可以下載到各種版本的CKEditor,包括完整版full、標準版standard、基礎版basic等。在頁面右側上方,還有可定製的下載,可以選擇Toolbar類型、插件、語言等。這裏我們選擇4.3版本的Full版本,下載後得到CKEditor_4.3_full.zip 。

  • CKEditor for java: 在http://ckeditor.com/download 頁面右側下部,可以下載到用於服務器端的工具,記得選擇for java版本。這裏選擇3.6.4版本。但是下載下來卻是 ckeditor-java-core-3.5.3.jar。不知道爲什麼。

  • CKFinder: 在 http://cksource.com/ckfinder/trial 頁面,可以下載到各種版本的CKFinder。仍然選擇java版。這裏我們下載的是2.4版本,下載後得到CKFinder_java_2.4.zip。

2. 安裝CKEditor和CKFinder

  • 解壓CKEditor_4.3_full.zip,把解壓得到的目錄 ckeditor 完全複製到網站根目錄下,也就是和WEB-INF同級。可以給這個目錄加上版本號,即ckeditor4.3。

  • ckeditor4.3/samples 完全刪掉,把 ckeditor4.3/lang 裏面除了en.js和zh-cn.js之外的文件刪掉,把 ckeditor4.3下的README.md, CHANGES.md刪掉。

  • 把 ckeditor-java-core-3.5.3.jar 放到yourapp/WEB-INF/lib

  • 解壓CKFinder_java_2.4.zip,得到ckfinder目錄。將 ckfinder/ckfinder_java_2.4\ckfinder\_sources\CKFinder for Java\WebApp\src\main\webapp\ckfinder 目錄完全複製到網站根目錄下,也就是和WEB-INF同級。可以給這個目錄加上版本號,即ckfinder2.4。

  • ckfinder2.4/_samples完全刪掉,把 ckfinder2.4/lang 下除了en.js和zh-cn.js之外的文件刪掉,把 ckfinder2.4 下的changelog.txt,install.txt,license.txt,translations.txt刪掉。

  • 把 CKFinderJava-2.4.war解壓,把ckfinder\CKFinderJava-2.4\WEB-INF\lib 下所有的jar包複製到yourapp/WEB-INF/lib下。

  • 把 ckfinder\CKFinderJava-2.4\WEB-INF\lib\config.xml複製到yourapp/WEB-INF下,並改名爲ckfinder.xml。

3. 在網頁裏使用CKEditor

Step1:找到需要放置CKEditor編輯器的頁面,引入CKEditor的js文件(${contextPath}是JSTL寫法,請改成你自己的路徑寫法,絕對路徑或者相對路徑)

<script type="text/javascript" src="${contextPath}/ckeditor4.3/ckeditor.js"></script>

Step2:在需要提交的form裏,寫一個<textarea>

<form id="detailForm" method="post">
    <textarea id="content" name="content"></textarea>
    <input type="button" value="保存" id="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不存在的錯誤。

 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');或者其他代碼得到編輯器的內容了,否則得到的很可能不是編輯器裏的內容。

4. CKEditor的三種配置方式

方式一:修改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">
    var editor = null;
    window.onload = function() {
        editor = CKEDITOR.replace( 'content', {
            customConfig:'${contextPath}/ckeditor4.3/myconfig.js'
        });
    };
</script>

方式三:在創建編輯器實例時指定配置

<script type="text/javascript">
    var editor = null;
    window.onload = function() {
        editor = CKEDITOR.replace( 'content',
            uiColor: '#9AB8F3',
            language:'zh-cn'
        });
    };
</script>

注意:使用第二種或者第三種方式的好處就在於,當你更新CKEditor版本時,不至於因爲直接複製了新的config.js而覆蓋掉個性配置。

5. CKEditor的一些配置選項

   完整的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

6. 關於CKEditor編輯器裏面回車的問題

   在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.3/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>之後不加換行
                    });
                }
            }
        });
    };
</script>

7. 將CKFinder整合進CKEditor

   沒有CKFinder,CKEditor作爲一個編輯器,也是可以正常使用的,但是無法在編輯器裏瀏覽服務器上的用戶上傳文件。所以要整合CKFinder。

   Step1:在頁面中引入CKFinder的js文件

<script type="text/javascript" src="${contextPath}/ckfinder2.4/ckfinder.js"></script>

Step2:創建CKFinder實例

<script type="text/javascript">
    var editor = null;
    window.onload = function() {
        editor = CKEDITOR.replace( 'content', {
            customConfig:'${contextPath}/ckeditor4.3/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>之後不加換行
                    });
                }
            }
        });
        CKFinder.setupCKEditor( editor, '${contextPath}/ckfinder2.4/' );
    };
</script>

   注意:第一個參數是CKEditor實例,第二個參數是ckfinder的目錄(最好寫絕對路徑),注意最後要帶斜槓'/'。    

   Step3:在CKEditor裏配置通過哪個頁面或者程序來瀏覽和上傳文件

   找到你的項目裏配置CKEditor的位置(參看本文CKEditor的三種配置方式部分),配置以下內容:

CKEDITOR.editorConfig = function( config ) {
    //其他一些配置
    filebrowserBrowseUrl = '/ckfinder2.4/ckfinder.html';
    filebrowserImageBrowseUrl = '/ckfinder2.4/ckfinder.html?type=Images';
    filebrowserFlashBrowseUrl = '/ckfinder2.4/ckfinder.html?type=Flash';
    filebrowserUploadUrl = '/ckfinder2.4/core/connector/java/connector.java?command=QuickUpload&type=Files';
    filebrowserImageUploadUrl = '/ckfinder2.4/core/connector/java/connector.java?command=QuickUpload&type=Images';
    filebrowserFlashUploadUrl = '/ckfinder2.4/core/connector/java/connector.java?command=QuickUpload&type=Flash';
};
上面的六行代碼,指定了通過ckfinder2.3.1/ckfinder.html來瀏覽圖片或者其他文件,通過/ckfinder2.3.1/core/connector/java/connector.java來上傳文件。

8. 配置CKFinder

   找到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,但實際上它不是一個圖片文件。

9. 在項目裏配置CKFinder的servlet

   找到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.4/core/connector/java/connector.java </url-pattern>
</servlet-mapping>
上面配置裏第一個init-param是指定CKFinder的配置文件位置。也就是上面第8部分提到的那個配置文件。

10. 更安全地使用CKFinder

   目前來說,CKFinder能夠正常地使用了。但是,即便沒有你的項目的管理權限,在瀏覽器中輸入yoursite/ckfinder2.3.1/ckfinder.html,也一樣能看到你的服務器上存放的那些文件,他們甚至可以上傳和刪除文件。有兩個地方可以加強CKFinder的安全性。

安全方法一:在yourapp/WEB-INF/ckfinder.xml裏配置訪問權限

<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.4/ckfinder.html時(包括點擊下圖的“瀏覽服務器”按鈕),檢查CKFinder_UserRole的值是什麼,它具有的權限是什麼。如果一個人沒有登錄系統,而是直接訪問yoursite/ckfinder2.4/ckfinder.html,那麼系統就會檢查到CKFinder_UserRole是null,他就看不到服務器上的文件。

安全方法二:自寫代碼檢查用戶是否有權限使用CKFinder

   在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.4/core/connector/java/connector.java </url-pattern>
</servlet-mapping>

在包路徑mypackage下創建一個類CKFinderConfiguration(包路徑和類名按照自己的項目代碼組織情況來取名),代碼如下:

import com.ckfinder.connector.configuration.Configuration;
public class CKFinderConfiguration extends Configuration {
    public CKFinderConfiguration(ServletConfig servletConfig) {
        super(servletConfig);
    }
    @Override
    protected Configuration createConfigurationInstance() {
        return new CKFinderConfiguration(this.servletConf);
    }
    @Override
    public boolean checkAuthentication(final HttpServletRequest request){
        String userid = request.getSession().getAttribute("userid");
        boolean logined = !userid.equals("");
        return logined;
    }
}

關鍵在於checkAuthentication()方法。可以在checkAuthentication()方法裏編寫關於用戶認證的一些判斷,比如用戶是否登錄系統,用戶是否有權限管理上傳文件。如果符合條件,就返回ture,否則返回false。

   兩種方法都可以讓ckfinder更安全,當然同時使用會更好。但是注意兩者區別,後者只能在比較粗的粒度進行控制。

11. 可能遇到的問

在使用ckfinder的時候可以能會遇到這樣的問題:

(1)因爲安全問題,文不能預覽。

193621434.png

原因是從ckfinder_java_2.4\ckfinder\_sources\CKFinder for Java\WebApp\src\main\webapp\WEB-INF中拷過來的config.xml默認是關閉ckfinder的;

解決辦法:false改爲ture

194413175.png

(2)文件上傳後預覽不正常

203107914.png原因:ckfinder路徑配置錯誤

解決辦法:加上項目路徑

203413971.png

解決後:

203534838.png

(3)設置預覽區內容

205437908.png

設置後:

205516485.png

(4)ckfinder上傳圖片名稱爲中文和圖片重命名爲中文時亂碼:

原因:tomcat中對uri的編碼方式和ckfinder的不同;

解決辦法:

在apache-tomcat-6.0.37\conf中修改server.xml爲:

120532360.png

(5)ckeditor破解:

不破解前:

203659955.png

破解方法:


修改代碼(ckfinder/ckfinder.js)
替換前:

if((V.eu&& !aa||Z)&&V.mj)

替換後:
if((V.eu&& !aa||Z)&&V.mj&&V.mj!=O)

修改代碼(ckeditor/pligins/pastefromword/filter/default.js)
查找 try{a=b.toHtml(a)}catch(d){alert(c.lang.pastefromword.error)}
註釋 /**try{a=b.toHtml(a)}catch(d){alert(c.lang.pastefromword.error)}**/



本文並非原創,只是在下面地址借鑑的,稍作改動,包括一些錯誤和版本升級。

http://www.cnblogs.com/yuepeng/archive/2013/04/01/2992097.html



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章