JAVA环境下HTML编辑器FCKeditor使用详解

本文大部分为转贴,部分为个人使用后发现的问题与理解。使用的是最新的 FCKeditor2.6Beta+FCKeditor   java2.3集成的java环境编辑器。这编辑器和csdn博客中使用的一样,只是少了两个功能:恢复上次提交和插入代码。不知道怎么弄的,谁知道可以 告诉我。一起交流,我也是刚开始接触这编辑器。

JAVA环境下HTML编辑器FCKeditor使用详解
 
JAVA环境下HTML编辑器FCKeditor使用详解

本文介绍FCKeditor在Java环境下的使用方法。

一、简介

功能:所见即所得,支持图片和Flash,工具栏可*配置,使用简单
兼容性:IE 5.5+、Firefox 1.5+、Safari 3.0+、Opera 9.50+、Netscape 7.1+、 Camino 1.0+
成熟度:使用广泛,被Baidu、CSDN等选用

二、下载 官方下载首页:http://www.fckeditor.net/download / ,当前版本为2.6Beta,需要下载FCKeditor 2.6Beta(FCKeditor_2.6b.zip )和FCKeditor.Java(FCKeditor-2.3.zip )。

三、部署

本例以WebRoot作为应用根路径,部署后的目录结构如下图所示:

JAVA环境下HTML编辑器FCKeditor使用详解

1、FCKeditor_2.5.1.zip解压,将fckeditor文件夹复制到/WebRoot/下

2、 FCKeditor-2.3.zip解压,将commons-fileupload.jar和FCKeditor-2.3.jar复制到/WebRoot /WEB-INF/lib/下,将src下面的FCKeditor.tld复制到/WebRoot/WEB-INF/下,把src目录下的java类的复 制到project的src目录下

3、修改/WebRoot/WEB-INF/web.xml文件,只定义了两个Servlet映射,并 且对上传文件的目录和允许哪些文件上传、拒绝哪些文件上传做了设置,请注意,这两个servlet的url-pattern我都在原来代码的前面加上了 /fckeditor,这是表示FCKeditor的根目录。另外SimpleUploader中的enabled属性要改成true,允许上传,增加内 容如下:
     < servlet >
        
< servlet-name > Connector </ servlet-name >
        
< servlet-class > com.fredck.FCKeditor.connector.ConnectorServlet </ servlet-class >
        
< init-param >
            
< param-name > baseDir </ param-name >
            
< param-value > /UserFiles/ </ param-value >
        
</ init-param >
        
< init-param >
            
< param-name > debug </ param-name >
            
< param-value > true </ param-value >
        
</ init-param >
        
< load-on-startup > 1 </ load-on-startup >
    
</ servlet >

    
< servlet >
        
< servlet-name > SimpleUploader </ servlet-name >
        
< servlet-class > com.fredck.FCKeditor.uploader.SimpleUploaderServlet </ servlet-class >
        
< init-param >
            
< param-name > baseDir </ param-name >
            
< param-value > /UserFiles/ </ param-value >
        
</ init-param >
        
< init-param >
            
< param-name > debug </ param-name >
            
< param-value > true </ param-value >
        
</ init-param >
        
< init-param >
            
< param-name > enabled </ param-name >
            
< param-value > true </ param-value >
        
</ init-param >
        
< init-param >
            
< param-name > AllowedExtensionsFile </ param-name >
            
< param-value ></ param-value >
        
</ init-param >
        
< init-param >
            
< param-name > DeniedExtensionsFile </ param-name >
            
< param-value > php|php3|php5|phtml|asp|aspx|ascx|jsp|cfm|cfc|pl|bat|exe|dll|reg|cgi </ param-value >
        
</ init-param >
        
< init-param >
            
< param-name > AllowedExtensionsImage </ param-name >
            
< param-value > jpg|gif|jpeg|png|bmp </ param-value >
        
</ init-param >
        
< init-param >
            
< param-name > DeniedExtensionsImage </ param-name >
            
< param-value ></ param-value >
        
</ init-param >
        
< init-param >
            
< param-name > AllowedExtensionsFlash </ param-name >
            
< param-value > swf|fla </ param-value >
        
</ init-param >
        
< init-param >
            
< param-name > DeniedExtensionsFlash </ param-name >
            
< param-value ></ param-value >
        
</ init-param >
        
< load-on-startup > 1 </ load-on-startup >
    
</ servlet >

  
< servlet-mapping >
    
< servlet-name > Connector </ servlet-name >
    
< url-pattern > / fckeditor/editor/filemanager/browser/default/connectors/jsp/connector </ url-pattern >
  
</ servlet-mapping >
  
  
< servlet-mapping >
    
< servlet-name > SimpleUploader </ servlet-name >
    
< url-pattern > / fckeditor/editor/filemanager/upload/simpleuploader </ url-pattern >
  
</ servlet-mapping >

4、修改/WebRoot/fckeditor/fckconfig.js,修改部分如下:

FCKConfig.BasePath + "filemanager/browser/default/browser.html?Connector=connectors/jsp/connector" ;
FCKConfig.BasePath + "filemanager/browser/default/browser.html?Type=Image&Connector=connectors/jsp/connector" ;
FCKConfig.BasePath + "filemanager/browser/default/browser.html?Type=Flash&Connector=connectors/jsp/connector" ;
FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=File' ;
FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=Image' ;
FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=Flash' ;


注意 :步骤 3、4设置了文件浏览和上传的配置,web.xml中Servlet的<url-pattern>要和fckconfig.js中的URL引 用一致。另外,我也把FCKeditor目录\fckeditor\editor\filemanager\下的connectors文件夹移到了 \fckeditor\editor\filemanager\browser\default\目录下,我也不知道这样做有什么用处,但好像不这样做就 会发生错误,希望大家指教。

四、使用

本例使用最直接的js方式,API和TagLib方式参见FCKeditor-2.3.zip解压后_samples下的例子。
fckdemo.jsp:

<% @    page contentType = " text/html;charset=GBK " %>
< html >
< head >
< title > FCKeditor Test </ title >
< script  type ="text/javascript"  src ="fckeditor/fckeditor.js" ></ script >
</ head >
< body >
< form  action ="fckdemo.jsp"  method ="post" >

<%   String  content = request.getParameter( " content " ); %>

< table  width =80% >
< tr >
    
< td  colspan =4  style ='text-align:center' >
    
< span >
        
< script  type ="text/javascript" >
            
var  oFCKeditor  =   new  FCKeditor('content'); // 表单的name,取值的依据
            oFCKeditor.BasePath = ' fckeditor / '; // 指定FCKeditor根路径,也就是fckeditor.js所在的路径
            oFCKeditor.Height = '200 ';/ /指定高度
            oFCKeditor.ToolbarSet
= 'Demo'; // 指定工具栏,这里使用了自定义的
            oFCKeditor.Value = " <%=content==null? "" :(content.replaceAll( " \ "" " ' " )) %> " ;// 默认值
            oFCKeditor.Create();
        </script>
    </span>
    </td>
</tr>
<tr><td align=center><input type=
" submit "  value= " 提交 " ></td></tr>
<tr><td>&nbsp;</td></tr>
<tr><td>取值(可直接保存至数据库):</td></tr>
<tr><td style=
" padding:10px; " ><%=content%></td></tr>
</table>

</form>
</body>
</html>

效果图:

JAVA环境下HTML编辑器FCKeditor使用详解


其实,我们也可以抛开JavaScript,而在服务器端使用标签来创建Web编辑器了。先在fckdemo.jsp:中引入标签库:

<% @ taglib uri = " http://fckeditor.net/tags-fckeditor "  prefix = " FCK "   %>

再在原来放JavaScript的地方,放如下代码:

JAVA环境下HTML编辑器FCKeditor使用详解 < FCK:editor  id ="EditorDefault"  basePath ="/editor /fckeditor /"
JAVA环境下HTML编辑器FCKeditor使用详解         imageBrowserURL
="/editor/fckeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=connectors/jsp/connector"
JAVA环境下HTML编辑器FCKeditor使用详解         linkBrowserURL
="/editor/fckeditor/editor/filemanager/browser/default/browser.html?Connector=connectors/jsp/connector"
JAVA环境下HTML编辑器FCKeditor使用详解         flashBrowserURL
="/editor/fckeditor/editor/filemanager/browser/default/browser.html?Type=Flash&Connector=connectors/jsp/connector"
JAVA环境下HTML编辑器FCKeditor使用详解         imageUploadURL
="/editor/fckeditor/editor/filemanager/upload/simpleuploader?Type=Image"
JAVA环境下HTML编辑器FCKeditor使用详解         linkUploadURL
="/editor /fckeditor/editor/filemanager/upload/simpleuploader?Type=File"
JAVA环境下HTML编辑器FCKeditor使用详解         flashUploadURL ="/editor/fckeditor/editor/filemanager/upload/simpleuploader?Type=Flash"
>
JAVA环境下HTML编辑器FCKeditor使用详解         This is some <
strong > sample text </ strong > . You are using  < href ="http://www.fredck.com/fckeditor/" > FCKeditor </ a >.
JAVA环境下HTML编辑器FCKeditor使用详解     
</ FCK:editor >

  
这里有一点一定要注意,那就是这里的属性都要避免使用相对路径。
刷新页面,又见编辑器,此时,可以顺利的上传文件了。整合编辑器的任务到此完成。
下一步,就是怎样对编辑器进行更多的控制了。

五、配置文件fckconfig.js

1、DefaultLanguage:缺省语言,可更改为“zh-cn”

2、添加常用的中文字体:在上面打开的文件中找到

JAVA环境下HTML编辑器FCKeditor使用详解FCKConfig.FontNames  =  'Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana' ;

加上几种我们常用的字体

JAVA环境下HTML编辑器FCKeditor使用详解FCKConfig.FontNames  =  '宋体;黑体;隶书;楷体_GB2312 ;Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana' ;


3、自定义工具栏:可修改或增加ToolbarSets,例如:

FCKConfig.ToolbarSets[ " Demo " =  [
    ['Bold','Italic','
- ','OrderedList','UnorderedList',' - ','Link','Unlink',' - ','TextColor','BGColor',' - ','Style',' - ','Image','Flash','Table']
] ;

4、EnterMode和ShiftEnterMode:“回车”和“Shift+回车”的换行行为,注释提示了可选模式

5、EditorAreaCss:编辑区样式文件

6、其他参数:

AutoDetectLanguage = true/false   自动检测语言 
BaseHref
= ""    相对链接的基地址 
ContentLangDirection
= " ltr/rtl "    默认文字方向 
ContextMenu
= 字符串数组 , 右键菜单的内容 
CustomConfigurationsPath
= ""    自定义配置文件路径和名称 
Debug
= true/false   是否开启调试功能 , 这样 , 当调用FCKDebug.Output()时 , 会在调试窗中输出内容 
EnableSourceXHTML
= true/false   为TRUE时 , 当由可视化界面切换到代码页时 , 把HTML处理成XHTML 
EnableXHTML
= true/false   是否允许使用XHTML取代HTML 
FillEmptyBlocks
= true/false   使用这个功能 , 可以将空的块级元素用空格来替代 
FontColors
= ""    设置显示颜色拾取器时文字颜色列表 
FontFormats
= ""    设置显示在文字格式列表中的命名 
FontNames
= ""    字体列表中的字体名 
FontSizes
= ""    字体大小中的字号列表 
ForcePasteAsPlainText
= true/false   强制粘贴为纯文本 
ForceSimpleAmpersand
= true/false   是否不把&符号转换为XML实体 
FormatIndentator
= ""    当在源码格式下缩进代码使用的字符 
FormatOutput
= true/false   当输出内容时是否自动格式化代码 
FormatSource
= true/false   在切换到代码视图时是否自动格式化代码 
FullPage
= true/false   是否允许编辑整个HTML文件 , 还是仅允许编辑BODY间的内容 
GeckoUseSPAN
= true/false   是否允许SPAN标记代替B , I , U标记 
IeSpellDownloadUrl
= "" 下载拼写检查器的网址 
ImageBrowser
= true/false   是否允许浏览服务器功能 
ImageBrowserURL
= ""    浏览服务器时运行的URL 
ImageBrowserWindowHeight
= ""    图像浏览器窗口高度 
ImageBrowserWindowWidth
= ""    图像浏览器窗口宽度 
LinkBrowser
= true/false   是否允许在插入链接时浏览服务器 
LinkBrowserURL
= ""    插入链接时浏览服务器的URL 
LinkBrowserWindowHeight
= "" 链接目标浏览器窗口高度 
LinkBrowserWindowWidth
= "" 链接目标浏览器窗口宽度 
Plugins
= object   注册插件 
PluginsPath
= ""    插件文件夹 
ShowBorders
= true/false   合并边框 
SkinPath
= ""    皮肤文件夹位置 
SmileyColumns
= 12    图符窗列数 
SmileyImages
= 字符数组   图符窗中图片文件名数组 
SmileyPath
= ""    图符文件夹路径 
SmileyWindowHeight   图符窗口高度 
SmileyWindowWidth   图符窗口宽度 
SpellChecker
= " ieSpell/Spellerpages "    设置拼写检查器 
StartupFocus
= true/false   开启时FOCUS到编辑器 
StylesXmlPath
= ""    设置定义CSS样式列表的XML文件的位置 
TabSpaces
= 4    TAB键产生的空格字符数 
ToolBarCanCollapse
= true/false   是否允许展开/折叠工具栏 
ToolbarSets
= object   允许使用TOOLBAR集合 
ToolbarStartExpanded
= true/false   开启是TOOLBAR是否展开 
UseBROnCarriageReturn
= true/false   当回车时是产生BR标记还是P或者DIV标记

六、自定义样式

工具栏的Style选项,是由fckconfig.js指定的配置文件来产生的:

FCKConfig.StylesXmlPath   =  FCKConfig.EditorPath  +  'fckstyles.xml' ;

可修改fckstyles.xml来自定义样式。

七、如何获取编辑器中插入的图片

从文章开头的功能设计我们可以看出,当用户编辑完文章后,我们应该能获取文章中插入的图片信息。怎样获取编辑器中的插入的图片呢?IT进行时 在他的文章FCKeditor的几点重要改进和使用心得,值得分享 中是这样做的:在上传图片的对话框的JavaScript中添加代码,使得当用户插入图片点OK后通知列表框,代码如下:

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

}  

  
我认为这个方法不好,第一,这个方法是侵入性的,需要修改FCKeditor的代码;第二,这种方法能够在用户插入图片的时候获得图片信息,但是如果用户插入的图片,接着又把图片从文章中删除了呢?这时候是无法跟踪的。

正确的思路应该是在编辑器失去焦点的时候,获取编辑器中的文档,通过DOM取得文章中所有的图片。代码如下:

function  FCKeditor_OnComplete( editorInstance )
{
    editorInstance.Events.AttachEvent( 'OnBlur', onEditorBlur ) ;
}

JAVA环境下HTML编辑器FCKeditor使用详解
function  onEditorBlur() {
    
var  oSelect  =  $( " img_select " );
    
for ( var  i = oSelect.options.length - 1 ; i > 0 ; i -- ) {
        oSelect.options[i] 
=   null ;
    }

    oEditor 
=  FCKeditorAPI.GetInstance('EditorDefault');
    
var  imgs  =  oEditor.EditorDocument.body.all.tags( " img " );
     
for ( var  i = 0 ; i  <  imgs.length; i ++ ) {
        
var  oOption  =  document.createElement( " option " );
        oOption.appendChild(document.createTextNode(imgs[i].src));
        oSelect.appendChild(oOption);
    }

}


八、如何给每一个用户分配一个单独的目录用来保存用户上传的图片。

经过我对FCKeditor的文档的反复阅读,发现FCKeditor自带的API没有办法实现这样的功能,所以,修改的重点还是在FCKeditor.java中。我们可以对源代码进行如下修改:

1、打开FCKeditor-2.3\src\com\fredck\FCKeditor\uploader目录下的SimpleUploaderServlet.java文件,找到SimpleUploaderServlet类的doPost方法,它的代码如下:

public   void  doPost(HttpServletRequest request, HttpServletResponse response)  throws  ServletException, IOException {

  
if  (debug) System.out.println( " --- BEGIN DOPOST --- " );

  response.setContentType(
" text/html; charset=UTF-8 " );
  response.setHeader(
" Cache-Control " , " no-cache " );
  PrintWriter out 
=  response.getWriter();
  

  String typeStr
= request.getParameter( " Type " );
  
  String currentPath
= baseDir + typeStr;

  String userName 
=  request.getSession().getUser().getName();
  currentPath 
=  currentPath  +  userName  +   " / " ;
  String currentDirPath
= getServletContext().getRealPath(currentPath);
  currentPath
= request.getContextPath() + currentPath;
  
  
if  (debug) System.out.println(currentDirPath);
  
  String retVal
= " 0 " ;
  String newName
= "" ;
  String fileUrl
= "" ;
  String errorMessage
= "" ;
  
  
if (enabled) {  
   DiskFileUpload upload 
=   new  DiskFileUpload();
   
try  {
    List items 
=  upload.parseRequest(request);
    
    Map fields
= new  HashMap();
    
    Iterator iter 
=  items.iterator();
    
while  (iter.hasNext()) {
        FileItem item 
=  (FileItem) iter.next();
        
if  (item.isFormField())
         fields.put(item.getFieldName(),item.getString());
        
else
         fields.put(item.getFieldName(),item);
    }
    FileItem uplFile
= (FileItem)fields.get( " NewFile " );
    String fileNameLong
= uplFile.getName();
    fileNameLong
= fileNameLong.replace( ' \ ' , ' / ' );
    String[] pathParts
= fileNameLong.split( " / " );
    String fileName
= pathParts[pathParts.length - 1 ];
    
    String nameWithoutExt
= getNameWithoutExtension(fileName);
    String ext
= getExtension(fileName);
    File pathToSave
= new  File(currentDirPath,fileName);
    fileUrl
= currentPath + " / " + fileName;
    
if (extIsAllowed(typeStr,ext)) {
     
int  counter = 1 ;
     
while (pathToSave.exists()){
      newName
= nameWithoutExt + " ( " + counter +