itstarting:IT進行時

          想自己所想,做自己所愛

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            28 隨筆 :: 3 文章 :: 55 評論 :: 0 Trackbacks

          以前公司購買過eWebEditor,功能應該還是不錯的,但即便到了現在,也還僅是一個IE only的版本,無法滿足現在差異化的需求。故前段時間下了最新的FCKeditor2.3.3版本下來(當然了,連帶java的integration),demo來看看,發現有幾個地方非常不爽:
          1、上載的文件,只能放在URL可及的地方(如默認只能放到嵌入應用路徑的/UserFiles/下);
          2、沒有明確的上載視頻的按鈕;
          3、圖片、FLASH、附件上載等,步驟多,復雜度高(想想,用戶不都是高手)。

          怎么辦呢,改!

          一、第一個就是增加一個FileLocatorServlet,思路很簡單:通過這個服務來定位文件,而不是之間產生鏈接,既是安全的考慮,也是應用集群的一個重要考慮點。而且原來的幾個servlet的配置羅嗦且重疊,難以讓人產生美感。所謂代碼勝千言,通過下面的web.xml大家應該可以看出修理的要點:

          ??1 <? xml?version="1.0"?encoding="ISO-8859-1" ?>
          ??2
          ??3 <! DOCTYPE?web-app
          ??4 ??PUBLIC?"-//Sun?Microsystems,?Inc.//DTD?Web?Application?2.2//EN"
          ??5 ??"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd" >
          ??6
          ??7 < web-app >
          ??8 ?? < display-name > FCKeditor?Test?Application </ display-name > ??
          ??9 ???? < context-param >
          ?10 ???????? <!-- ?setting?the?FCKecitor?context?based?parameters? -->
          ?11 ???????? <!-- ?baseDir?means?the?root?of?the?uploaded?file/image/flash?stored?
          ?12 ?????????????the?prefix?of?'file:/'?means?strore?in?a?file?system?root?that?cannot?get?from?webapp?url
          ?13 ???????? -->
          ?14 ???????? < param-name > baseDir </ param-name >
          ?15 ???????? < param-value > file:/C:/Temp/FCKeditorUpload/ </ param-value >
          ?16 ???? </ context-param > ?
          ?17
          ?18 ???? < context-param >
          ?19 ???????? <!-- ?
          ?20 ?????????????if?the?baseDir?prefix?by?'file:/',please?set?it.
          ?21 ???????? -->
          ?22 ???????? < param-name > fileLocator </ param-name >
          ?23 ???????? < param-value > /editor/filemanager/browser/default/service/jsp/filelocator </ param-value >
          ?24 ???? </ context-param > ?
          ?25
          ?26 ???? < context-param >
          ?27 ???????? <!-- ?
          ?28 ?????????????debug?setting,true?means?verbose?output?to?the?console.
          ?29 ???????? -->
          ?30 ???????? < param-name > debug </ param-name >
          ?31 ???????? < param-value > true </ param-value >
          ?32 ???? </ context-param > ?
          ?33
          ?34 ???? < context-param >
          ?35 ???????? <!-- ?
          ?36 ?????????????enabled?setting,true?means?upload?enabled.
          ?37 ???????? -->
          ?38 ???????? < param-name > enabled </ param-name >
          ?39 ???????? < param-value > true </ param-value >
          ?40 ???? </ context-param > ?
          ?41
          ?42 ???? < context-param >
          ?43 ???????? <!-- ?
          ?44 ?????????????encoding,the?response?encoding?of?the?file/image/flash,default?is?UTF-8
          ?45 ???????? -->
          ?46 ???????? < param-name > encoding </ param-name >
          ?47 ???????? < param-value > UTF-8 </ param-value >
          ?48 ???? </ context-param > ?
          ?49
          ?50 ???? < context-param >
          ?51 ???????? <!-- ?
          ?52 ?????????????contentTypeMapping,a?map?for?the?response?ContentType
          ?53 ???????? -->
          ?54 ???????? < param-name > contentTypeMapping </ param-name >
          ?55 ???????? < param-value > doc=application/vnd.ms-word
          ?56 ????????|xls=application/vnd.ms-excel
          ?57 ????????|jpg=image/jpeg
          ?58 ????????|gif=image/gif
          ?59 ????????|swf=application/x-shockwave-flash
          ?60 ????????|avi=video/x-msvideo
          ?61 ???????? </ param-value >
          ?62 ???? </ context-param > ?
          ?63
          ?64 ???? < context-param >
          ?65 ???????? <!-- ?
          ?66 ?????????????allowedExtensionsFile,the?logic?is?'Not?allowed?means?deny.'
          ?67 ???????? -->
          ?68 ???????? < param-name > allowedExtensionsFile </ param-name >
          ?69 ???????? < param-value > doc|xls|pdf|avi </ param-value >
          ?70 ???? </ context-param > ?
          ?71
          ?72 ???? < context-param >
          ?73 ???????? <!-- ?
          ?74 ?????????????allowedExtensionsImage,the?logic?is?'Not?allowed?means?deny.'
          ?75 ???????? -->
          ?76 ???????? < param-name > allowedExtensionsImage </ param-name >
          ?77 ???????? < param-value > jpg|gif|png </ param-value >
          ?78 ???? </ context-param > ?
          ?79
          ?80 ???? < context-param >
          ?81 ???????? <!-- ?
          ?82 ?????????????allowedExtensionsFlash,the?logic?is?'Not?allowed?means?deny.'
          ?83 ???????? -->
          ?84 ???????? < param-name > allowedExtensionsFlash </ param-name >
          ?85 ???????? < param-value > swf|fla </ param-value >
          ?86 ???? </ context-param >
          ?87
          ?88 ???? < servlet >
          ?89 ???????? < servlet-name > Connector </ servlet-name >
          ?90 ???????? < servlet-class > com.fredck.FCKeditor.connector.ConnectorServlet </ servlet-class >
          ?91 ???????? < load-on-startup > 1 </ load-on-startup >
          ?92 ???? </ servlet >
          ?93 ????
          ?94 ???? < servlet >
          ?95 ???????? < servlet-name > FileLocator </ servlet-name >
          ?96 ???????? < servlet-class > com.fredck.FCKeditor.service.FileLocatorServlet </ servlet-class >
          ?97 ???????? < load-on-startup > 1 </ load-on-startup >
          ?98 ???? </ servlet >
          ?99
          100 ???? < servlet >
          101 ???????? < servlet-name > SimpleUploader </ servlet-name >
          102 ???????? < servlet-class > com.fredck.FCKeditor.uploader.SimpleUploaderServlet </ servlet-class >
          103 ???????? < load-on-startup > 1 </ load-on-startup >
          104 ???? </ servlet >
          105
          106 ?? < servlet-mapping >
          107 ???? < servlet-name > Connector </ servlet-name >
          108 ???? < url-pattern > /editor/filemanager/browser/default/connectors/jsp/connector </ url-pattern >
          109 ?? </ servlet-mapping >
          110 ??
          111 ?? < servlet-mapping >
          112 ???? < servlet-name > SimpleUploader </ servlet-name >
          113 ???? < url-pattern > /editor/filemanager/upload/simpleuploader </ url-pattern >
          114 ?? </ servlet-mapping > ??
          115 ??
          116 ?? < servlet-mapping >
          117 ???? < servlet-name > FileLocator </ servlet-name >
          118 ???? < url-pattern > /editor/filemanager/browser/default/service/jsp/filelocator </ url-pattern >
          119 ?? </ servlet-mapping > ??
          120
          121 </ web-app >

          連帶FCKeditorConfigurations.java一并修理,配置統一且singleton。關鍵代碼為:

          ?1
          ?2 ???? /**
          ?3 ?????*?Make?the?configuration?sigleton
          ?4 ?????*? @param ?sc
          ?5 ?????*? @return ?the?static?configuration?map
          ?6 ????? */

          ?7 ???? public ? static ?Map?getContextConfigurationsInstance(ServletContext?sc) {
          ?8 ???????? if (contextConfigurations == null ) {
          ?9 ????????????initContextConfigurations(sc);
          10 ????????}

          11 ???????? return ?contextConfigurations;
          12 ????}

          13 ????
          14 ???? /**
          15 ?????*?Init?all?the?FCKeditor?configuration.
          16 ?????*?add?by?zhengxq
          17 ?????*? @param ?sc
          18 ????? */

          19 ???? private ? static ? void ?initContextConfigurations(ServletContext?sc) {
          20 ???????? if ?(debug)
          21 ????????????System.out.println( " \r\n----?FCKeditorConfigurations?for?java?initialization?started?---- " );
          22 ????????
          23 ????????String?baseDir? = ?sc.getInitParameter( " baseDir " );
          24 ????????String?fileLocator? = ?sc.getInitParameter( " fileLocator " );
          25 ????????String?debugStr? = ?sc.getInitParameter( " debug " );
          26 ????????String?enabledStr? = ?sc.getInitParameter( " enabled " );????????
          27 ????????String?encoding? = ?sc.getInitParameter( " encoding " );
          28 ????????String?contentTypeMapping? = ?sc.getInitParameter( " contentTypeMapping " );
          29 ????????String?AllowedExtensionsFile? = ?sc.getInitParameter( " allowedExtensionsFile " );
          30 ????????String?AllowedExtensionsImage? = ?sc.getInitParameter( " allowedExtensionsImage " );
          31 ????????String?AllowedExtensionsFlash? = ?sc.getInitParameter( " allowedExtensionsFlash " );
          32 ????????
          33 ????????debug? = ?( new ?Boolean(debugStr)).booleanValue();
          34 ????????encoding? = ?(encoding == null ? || ?encoding.length() == 0 ) ? " UTF-8 " :encoding;
          35 ????????
          36 ???????? if (baseDir == null ? || ?baseDir.length() == 0 )?baseDir? = ?defaultBaseDir;
          37 ????????String?realBaseDir? = ?defaultBaseDir;
          38 ???????? if ?(baseDir.startsWith(fileSystemUriPrefix))? {
          39 ????????????realBaseDir? = ?baseDir.substring(fileSystemUriPrefix.length());????????????
          40 ????????}
          ? else ? {
          41 ????????????realBaseDir? = ?sc.getRealPath(baseDir);
          42 ????????????fileLocator? = ? null ; // no?use?and?should?set?null
          43 ????????}

          44 ????????File?baseFile = new ?File(realBaseDir);
          45 ???????? if ( ! baseFile.exists()) {
          46 ????????????baseFile.mkdir();
          47 ????????}

          48 ????????contextConfigurations? = ? new ?HashMap();
          49 ????????contextConfigurations.put( " baseDir " ,baseDir);
          50 ????????contextConfigurations.put( " realBaseDir " ,realBaseDir);
          51 ????????contextConfigurations.put( " fileLocator " ,fileLocator);
          52 ????????contextConfigurations.put( " debug " ,debugStr);
          53 ????????contextConfigurations.put( " enabled " ,enabledStr);
          54 ????????contextConfigurations.put( " encoding " ,encoding);
          55 ????????contextConfigurations.put( " contentTypeMapping " ,contentTypeMappingToMap(contentTypeMapping));
          56 ????????contextConfigurations.put( " allowedExtensionsFile " ,stringToArrayList(AllowedExtensionsFile));
          57 ????????contextConfigurations.put( " allowedExtensionsImage " ,stringToArrayList(AllowedExtensionsImage));
          58 ????????contextConfigurations.put( " allowedExtensionsFlash " ,stringToArrayList(AllowedExtensionsFlash));
          59 ????????
          60 ???????? if ?(debug)
          61 ????????????System.out.println( " \r\n----?FCKeditorConfigurations?for?java?initialization?end?---- " );
          62 ????????
          63 ????}


          FileLocatorServlet.java也很簡單,無非就是文件的物理定位和文件流的輸出:

          ?1 String?type? = ?request.getParameter( " Type " );
          ?2 ????????String?fileName? = ?request.getParameter( " FileName " );
          ?3
          ?4 ????????String?realFilePath? = ?config.get( " realBaseDir " )? + ?type? + ? " / " ? + ?fileName;
          ?5 ????????File?file? = ? new ?File(realFilePath);
          ?6 ???????? if ?(file.exists())? {
          ?7 ????????????response.setHeader( " Content-Transfer-Encoding " ,? " base64 " );
          ?8 ????????????response.setHeader( " Cache-Control " ,? " no-store " );
          ?9 ????????????response.setHeader( " Pragma " ,? " no-cache " );
          10 ????????????response.setDateHeader( " Expires " ,? 0 );
          11 ????????????response.setContentType(getContentTypeByFileExt(fileName.substring(fileName.lastIndexOf( " . " ))));
          12 ????????????
          13 ????????????ServletOutputStream?out? = ?response.getOutputStream();????????????
          14 ????????????InputStream?in? = ? new ?FileInputStream(file);
          15 ????????????BufferedInputStream?bis? = ? new ?BufferedInputStream(in);
          16 ????????????BufferedOutputStream?bos? = ? new ?BufferedOutputStream(out);
          17 ???????????? byte []?buff? = ? new ? byte [ 2048 ];
          18 ???????????? int ?bytesRead;
          19 ???????????? while ?( - 1 ? != ?(bytesRead? = ?bis.read(buff,? 0 ,?buff.length)))? {
          20 ????????????????bos.write(buff,? 0 ,?bytesRead);
          21 ????????????}

          22 ???????????? if ?(bis? != ? null )? {
          23 ????????????????bis.close();
          24 ????????????}

          25 ???????????? if ?(bos? != ? null )? {
          26 ????????????????bos.close();
          27 ????????????}

          28 ????????}
          ? else ? {
          29 ???????????? throw ? new ?FileNotFoundException(fileName);
          30 ????????}

          上述改動已經提交給了FCKeditor,如果大家真的有興趣,可以去找里面我所提交的patch。

          二、至于上述的2、3問題,同樣,動手即可解決,在此略過。

          過程中倒是碰到幾個有意思的問題,成了花絮,其實也是使用FCKeditor的一些心得,寫寫可能還有點意思:
          1、如何取得FCKeditor的值?
          答案:這是我們常常干的事情:取得這個值并賦值給某個hidden,再合法性檢查+submit等。怎么取得呢?這樣:

          1 ???? var ?oEditor? = ?FCKeditorAPI.GetInstance('editor')?;
          2 ???? // Get?the?editor?contents?in?XHTML.
          3 ???? // alert(?oEditor.GetXHTML(true)?)?;????//?"true"?means?you?want?it?formatted.
          4 ????document.all( " tip.c_content " ).value = oEditor.GetXHTML( true );

          2、如何使得FCKeditor接收tab鍵?
          答案:我們希望界面元素按照外面的安排進行tab切換,但FCKeditor怎么能做到呢?也有辦法:

          1 function ?focusIframeOnTab(caller,?tabTargetId,?callEvent) {
          2 ???????????????? // ?If?keypress?TAB?and?not?SHIFT+TAB?
          3 ???????????????? if (callEvent.keyCode? == ? 9 ? && ? ! callEvent.shiftKey)
          4 ????????????????????document.getElementById(tabTargetId).contentWindow.focus();
          5 ????????????}

          光光有個函數頂個什么用,還要這樣:在之前的那個界面元素中加上下面的事件,如使用struts的tag的化,這樣就可以了:

          < html:text? property ="tip.c_title" ?style ="width:450px" ?tabindex ="1" ?onkeydown ="focusIframeOnTab(this,?'editor___Frame',event);if(!document.all)?return?false;" />

          這點是google了半天最終在FCKeditor的FAQ中找到的,看來以后用開源的軟件第一件事情就是看FAQ,錯不了!

          3、如何希望在FCKeditor加載完畢后做點什么事情?
          答案:也很簡單,編寫自己的FCKeditor_OnComplete函數,如:

          function ?FCKeditor_OnComplete(?editorInstance?)? {
          ????????????????window.status?
          = ?editorInstance.Description?;
          ????????????}


          4、如果在圖片、FLASH等界面中上載了東西后,希望能告訴自己的表單,怎么做?
          答案:這個花了我不少看代碼和調試時間!其實這里的關鍵就是如何獲取嵌入FCKeditor的那個window,這樣就可以了,在對應的js文件(如editor\dialog\fck_image\fck_image.js)中的ok方法的最后加入:


          ????
          // edit?by?zhengxq
          ???? try {????????
          ????????
          var ?obj? = ?window.dialogArguments.Editor.parent.document;
          ????????obj.getElementById(
          " tip.c_tip_has_pic " ).value? = ? " 1 " ;
          ????}
          catch (e) {} ????

          關鍵就是:window.dialogArguments.Editor.parent.document,這個能夠找到對應窗口的引用,有了這個,還不會控制嗎?!

          posted on 2007-03-11 20:20 IT進行時 閱讀(6870) 評論(12)  編輯  收藏 所屬分類: Java Tips

          評論

          # re: FCKeditor的幾點重要改進和使用心得,值得分享 2007-03-11 21:22 祎恬凡
          謝謝摟住共享!q是多少,好隨時請教阿!
            回復  更多評論
            

          # re: FCKeditor的幾點重要改進和使用心得,值得分享 2007-03-12 09:36 darkbluefeeling
          不認同FileLocatorServlet.java的做法。web的集群已經是非常成熟的技術,不存在你提到的風險,而且web服務器處理這行靜態文件效率非常高。樓主這樣把靜態文件丟給應用服務器去做,如果訪問量比較高的話,問題會非常多。  回復  更多評論
            

          # re: FCKeditor的幾點重要改進和使用心得,值得分享 2007-03-12 17:11 IT進行時
          to darkbluefeeling:
          謝謝反饋!
          據我所知,對于基于session上載的文件,一般的app中間件(包括IBM WAS5/6)都不具備集群同步的能力,難道你另有高招?請不吝賜教。  回復  更多評論
            

          # re: FCKeditor的幾點重要改進和使用心得,值得分享[未登錄] 2007-03-13 10:28 jacky
          我也是類似的修改了.  回復  更多評論
            

          # re: FCKeditor的幾點重要改進和使用心得,值得分享 2007-07-14 11:10 gok
          請問樓上知不知道怎樣截獲FCKeditor的文本編輯區的按鍵事件,我弄了很久,都沒有成功。  回復  更多評論
            

          # re: FCKeditor的幾點重要改進和使用心得,值得分享 2007-11-30 11:22 IT進行時
          有基于二次開發的API的,可以找找看。  回復  更多評論
            

          # re: FCKeditor的幾點重要改進和使用心得,值得分享 2008-02-18 23:07 FastUnit
          收藏。  回復  更多評論
            

          # re: FCKeditor的幾點重要改進和使用心得,值得分享 2008-03-22 21:38 flyfan
          剛學用FCKeditor,你的文章受益不淺,轉貼了  回復  更多評論
            

          # re: FCKeditor的幾點重要改進和使用心得,值得分享 2010-03-10 10:43 王彬
          我問個問題,FCKeditor編輯器里面的內容我怎么添加到隱藏的textarea里
            回復  更多評論
            

          # re: FCKeditor的幾點重要改進和使用心得,值得分享 2010-03-10 11:10 IT進行時
          to 王彬:

          文檔你可能沒看清楚,或者我沒理解你的意思。
          如果要添加到textarea,意味著兩步:

          //1、取得fckeditor實例;
          var oEditor = FCKeditorAPI.GetInstance('editor') ;

          //2、取得fckeditor的值并賦予textarea:
          // "true" means you want it formatted.
          document.getElementById(你的textarea對象).value = oEditor.GetXHTML( true );   回復  更多評論
            

          # re: FCKeditor的幾點重要改進和使用心得,值得分享 2010-03-10 11:33 王彬
          @IT進行時
          直接在window.onload這個js里面加嗎
          還是加載后加個function方法,我覺得我的主要問題應該是他沒有實時把編輯器里面的內容寫到textarea里  回復  更多評論
            

          # re: FCKeditor的幾點重要改進和使用心得,值得分享 2011-08-05 11:05 后生
          我想在FCK上實現,光標在“源代碼”按鈕【左上角】后,能夠在源代碼下相同。。。

          例如在設計模式時,光標在文章最后。
          現在點擊源代碼按鈕后,光標也在源代碼最后~  回復  更多評論
            

          主站蜘蛛池模板: 额尔古纳市| 荣成市| 应城市| 拜城县| 温宿县| 固安县| 连城县| 德安县| 方城县| 霞浦县| 齐齐哈尔市| 湘潭市| 蒙城县| 双鸭山市| 托克托县| 阜康市| 福鼎市| 宕昌县| 乐安县| 乐东| 兴山县| 内丘县| 济阳县| 河池市| 抚松县| 遵义县| 彰化县| 舟山市| 井研县| 海城市| 辽源市| 黑龙江省| 玉山县| 望奎县| 舒兰市| 城步| 礼泉县| 象州县| 成武县| 齐河县| 阿鲁科尔沁旗|