FCKeditor簡介:
FCKeditor是一個專門使用在網頁上屬於開放源代碼的所見即所得文字編輯器。它志於輕量化,不需要太復雜的安裝步驟即可使用。它可和PHP、 JavaScript、ASP、ASP.NET、ColdFusion、Java、以及ABAP等不同的編程語言相結合。“FCKeditor”名稱中的 “FCK” 是這個編輯器的作者的名字Frederico Caldeira Knabben的縮寫。FCKeditor 相容於絕大部分的網頁瀏覽器.
如果要將fckeditor跑起來,首先需要jar包,還有FCKeditor_2.6.4.1.zip,這些大家都可以到www.fckeditor.net官方網站上下載,這里的需要的jar包我給大家列出來:
commons-fileupload-1.2.1.jar
commons-io-1.3.2.jar
fckeditor-java-core-2.4.jar
java-core-2.4.jar
slf4j-api-1.5.2.jar
slf4j-simple-1.5.2.jar
csdn上還有資源,大家都可以去下載
接下來如何調用fckeditor呢?有兩種方式:通過javascript調用和jsp的自定義的標簽來使用
將解壓后的FckEditor_2.6.3放在web 工程的webroot下面
然后新建一個html,在其中引入fckeditor文件夾中的fckeditor.js,引入如下:<script type="text/javascript" src="http://ayue05.blog.163.com/blog/fckeditor/fckeditor.js">
接下來:介紹第一種方法:
<script type="text/javascript">
var fckeditor=new FCKeditor('FCKeditor1');//新建一個fckeditor實例
fckeditor.BasePath="/fckeditor/";//設置編輯器的位置,該位置一定要以/結尾,這個basepath是指 fckeditor文件夾下所有文件的地址,默認值是這個,但是我們一般前面還要加上工程的名字,如/prj/fckeditor/這樣
fckeditor.Create();//創建並且調用一個fckeditor編輯器
</script>
第二種方法:通過jsp自定義標簽來完成調用
可以參考:
@演示工程fckeditor-java-demo-2.4.war :jsp文件夾--》sample02.html
@fckeditor-java-2.4文檔
<%@ taglib="http://java.fckeditor.net"%>
<FCK:editor instanceName="myEditor" basePath="/fckeditor" value="this is value"></FCK:editor><!--注意這里必須寫value值,並且值不能為空字符串-->
注意:basePath以/開頭,並且這個/代表當前工程的路徑
完成上述步驟后,即可通過瀏覽器訪問該html文件了,大家就可以看到一個簡單的 fckeditor界面了,但是很多東西還是需要自己配置才能使用的
首先大家可以去www.fckeditor.net官方網站上下載fckeditor-java-demo-2.4.war然后直接丟到tomcat中,即可在瀏覽器中瀏覽頁面http://localhost:8080/fckeditor-java-demo-2.4/
還要下載FCKeditor_2.6.4.1.zip和fckeditor-java-2.4-bin.zip
配置——使用配置文件
fckconfig.js即主配置文件,如果我們要修改配置,就需要修改該文件中的屬性,一般我們可以直接修改該配置文件,不過我們不采取這樣的做法,一般我們是新建一個配置文件myconfig。js來覆蓋默認的配置文件
比如,我們新建了一個myconfig.js然后在里面寫上FCKConfig.AutoDetectLanguage=false; FCKConfig.DefaultLanguage='fr'將原本配置文件中的自動發現語言改為false,並指定默認的語言為法語 fr
那么當我們寫完配置文件后,如果應用呢?有兩種方法:
1)在原本的配置文件中fckconfig.js中的 FCKConfig.CustomConfigurationPath=''改為 FCKConfig.CustomConfigurationPath='/fck/myconfig.js'
注意:這種方法會修改所有的關於fckeditor頁面的屬性
2)在頁面中來制定。在調用fck的 代碼中添加如下語句:fckeditor.Config["CustomConfigurationsPath"]="/test /myconfig.js";
注意:這種方法只會修改所在頁面的fckeditor的屬性,一般工程發布的時候不確定在哪,所以test應跟換為 FCKeditor.EditorPath,它指的是 fckeditor文件夾下的editor文件夾
總結一下配置 fckeditor:
1)直接修改主配置文件,fckconfig.js
2)定義單獨的配置文件(只需要寫需要修改的配置項)
3)在頁面的代碼中對FCKeditor的實例進行配置
配置加載順序:
1)加載主配置文件fckconfig.js
2)加載自定義的配置文件(如果有),覆蓋相同的配置項(注意是相同的)
3)使用對實例的配置覆蓋相同的配置項(只對當前實例有效)
注意事項:
1.永遠都不要刪除主配置文件:fckconfig.js
2.系統會自動偵測並運行適當的界面語言(默認,可以修改)
3.修改配置后要清空瀏覽器緩存,以免影響結果(或訪問時強制刷新也可以)
一般需要修改的配置
1)自定義ToolbarSet,去掉一些功能
2)加上幾種常用的字體
3)修改“回車”和 “shift+回車”的換行行為:原本fck的回車鍵的效果是換段落,而shift+回車的效果是換行,所以我們要將這兩種效果顛倒一下
4)修改編輯區樣式文件
5)更換表情圖片
關 於設置ToolbarSet:首先在fckconfig.js找到FCKConfig.ToolbarSets[]中括號中可以指定 toolbar的名字,比如mytoolbar,然后在調用fck的頁面設置一下toolbarset為mytoolbar即 fckeditor.ToolbarSet="mytoolbar",這樣就可以了
關於加上幾種字體:只需要FCKConfig.FontNames中添加我們想添加的字體,注意它會提示不讓保存,則設置myconfig.js文件properties的resources選項中的text file encoding ,只能設置為utf-8
關於修改回車換行換段:
FCKConfig.ShiftEnterMode = 'p' ; // p | div | br
FCKConfig.EnterMode = 'br' ; // p | div | br
改成這樣,原本是將兩行互相調換的
關於編輯區樣式文件:在主配置文件fckconfig.js文件中,找到FCKConfig.EditorAreaCSS = FCKConfig.BasePath + 'css/fck_editorarea.css' ;
我們會發現所有的樣式都是在editor文件夾下的css文件夾下的fck_editorarea.css文件中的,
關於添加自定義表情:
FCKConfig.SmileyPath = FCKConfig.BasePath + 'images/smiley/msn/' ;//表示表情圖片所在文件夾
FCKConfig.SmileyImages = ['regular_smile.gif','sad_smile.gif','wink_smile.gif','teeth_smile.gif','confused_smile.gif','tounge_smile.gif','embaressed_smile.gif','omg_smile.gif','whatchutalkingabout_smile.gif','angry_smile.gif','angel_smile.gif','shades_smile.gif','devil_smile.gif','cry_smile.gif','lightbulb.gif','thumbs_down.gif','thumbs_up.gif','heart.gif','broken_heart.gif','kiss.gif','envelope.gif'] ;//文件夾中的每幅圖片,其內容是個數組
FCKConfig.SmileyColumns = 8 ;//表示每列顯示的表情圖片數
FCKConfig.SmileyWindowWidth= 320 ;//表示彈出的對話框的寬度
FCKConfig.SmileyWindowHeight= 210 ;//表示彈出的對話框的高度
如果我們想將自己的一副圖片加入到表情中,則首先將圖片copy到文件夾中,然后再數組中加入該圖片的名字,即可
也可以將自己的一個圖片文件夾作為表情圖片文件夾,則需要指定SmileyPath為我們自己的圖片文件夾,然后將文件夾中每個圖片名稱羅列在數組中
這時我們可能遇到,如果圖片太多,則會顯示的很長很長,即使我們設置了SmileyWindowWidth和SmileyWindowHeight也沒有用,這時我們右擊,查看其源文件,應該是http://localhost:8080/fck/fckeditor/editor/dialog/fck_smiley.html這 個html,然后我們找到打開,window.onload事件中dialog.SetAutoSize(true) ;我們將它改為false,這樣就會按照我們指定的寬高來顯示了,可是會少了很多圖片表情,所以我們還要在<body style="overflow: hidden">這里,將hidden改為scroll,如果圖片過多在指定的寬高無法顯示,則會自動添加滾動條
最后提示、:FCKConfig.BasePath和調用fckeditor時指定的BasePath(FCKeditor BathPath)不是同一個,其值也不一樣
文件上傳:這是很常用的
我們可以參照 D:\JAVA\FCKeditor\fckeditor-java-2.4-bin\fckeditor-java-2.4\site \connector.html,該文件,
第一步:
Declare the ConnectorServlet in your web.xml
<web-app version="2.4">
<servlet>
<servlet-name>Connector</servlet-name>
<servlet-class>
net.fckeditor.connector.ConnectorServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Connector</servlet-name>
<url-pattern>
/fckeditor/editor/filemanager/connectors/*
</url-pattern>
</servlet-mapping>
</web-app>
配置文件
第二步:
在工程的src下新建一個fckeditor.properties文件,文件內容如下:
connector.userActionImpl=net.fckeditor.requestcycle.impl.UserActionImpl
這樣就可以簡單使用上傳了
在上傳文件名為中文的時候會出現名稱會出現亂碼,如何解決?
首先要知道這個亂碼可能是提交的內容是否出現不正確的編碼問題,或者是提交至服務器端處理時出現的問題
首 先我們找到對應的 editor->filemanager->default->frmupload.html我們發現它是以utf-8的編碼顯示的, 沒有任何問題,接着我們看愛你給哪個文件處理的,就在我們剛配置的web.xml文件中已經指定了 net.fckeditor.connector.ConnectorServlet,是這個,這個servlet在referenced libraries下面的fckeditor-java-core。jar包下的net。fckeditor。connector下的servlet,然 后我們要attach source,關聯上源碼,源碼是fckeditor-java-2.4-src.zip,完了之后,按ctrl+o,然后看它的dopost方法,在 List<FileItem> item=upload.parseRequest(request);這里是需要指定編碼的。但這個文件我們修改不了,所以要復制過來,在src下新建 一個package,新建同樣名稱的servlet,然后粘貼,在try之前寫上:upload.setHeaderEncoding("utf- 8");接着必須要在web.xml文件中修改
<servlet-class>
net.fckeditor.connector.ConnectorServlet修改這里,將前面的包名給改了
</servlet-class>
除此之外,還會在創建中文目錄名時出現亂碼
仍然在ConnectorServlet文件中在doget方法中,找到 NewFoldName,然后添上:
String tempstr=request.getParameter("NowFoldName");
tempstr=new String(temstr.getBytes("iso8859-1"),"utf-8");
String newFoldStr=……(tempstr)
引用中文名稱的圖片不能正常顯示?
方法一:修改tomcat連接器的配置:tomcat6.0-->conf-->server.xml-->
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
在這個后面增加一個屬性:URIEncoding="utf-8"
修改完后,需要重新啟動 tomcat服務器,不過該種方法不推薦使用
方法二:避免使用中文名稱的圖片,即在對中文名稱的圖片進行保存時,讓其不以中文形式保存,改以uuid編碼方式
在 ConnectorServlet文件中,dopost方法中找到保存文件的地方,pathToSave然后添加如下:
filename=UUID.randomUUID().toString()+"."+extension;
以上講述比較理論,大家可以我已經配置好的ConnectorServlet類,代碼如下:
- package net;
- import java.io.*;
- import javax.servlet.*;
- import javax.servlet.http.*;
- import java.util.*;
- import java.util.regex.Pattern;
- import org.apache.commons.fileupload.*;
- import javax.xml.parsers.*;
- import org.w3c.dom.*;
- import javax.xml.transform.*;
- import javax.xml.transform.dom.DOMSource;
- import javax.xml.transform.stream.StreamResult;
- public class ConnectorServlet extends HttpServlet {
- private static String baseDir;
- private static boolean debug = false;
- // 允許上傳的Image類型的文件類型
- private static String allowedType;
- // 不允許上傳的File類型的文件類行
- private static String unallowedFileType;
- /**
- * 初始化 servlet.
- * Retrieve from the servlet configuration the "baseDir" which is the root
- * of the file repository:
- * If not specified the value of "/UserFiles/" will be used.
- *
- */
- public void init() throws ServletException {
- baseDir = getInitParameter("baseDir");
- debug = (new Boolean(getInitParameter("debug"))).booleanValue();
- // 設置baseDir的默認值
- if (baseDir == null)
- baseDir = "/UserFiles/";
- String realBaseDir = getServletContext().getRealPath(baseDir);
- File baseFile = new File(realBaseDir);
- // 建立目錄
- if (!baseFile.exists()) {
- baseFile.mkdir();
- }
- // 得到允許上傳的Image類型,從web.xml配置
- allowedType = "|jpg|gif|jpeg|png|bmp|";
- unallowedFileType = "abc";
- }
- /**
- * doGet方法處理 (GetFolders, GetFoldersAndFiles, CreateFolder).
- * 此servlet接收如下參數
- * connector?Command=CommandName&Type=ResourceType&CurrentFolder=FolderPath
- * 它最后返回xml
- */
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/xml; charset=UTF-8");
- response.setHeader("Cache-Control", "no-cache");
- PrintWriter out = response.getWriter();
- String commandStr = request.getParameter("Command");
- // 得到文件類型,Image,File,Flash,Media
- String typeStr = request.getParameter("Type");
- // 得到當前的目錄
- String currentFolderStr = request.getParameter("CurrentFolder");
- // 得到當前目錄的真實路徑
- String currentPath = baseDir + typeStr + currentFolderStr;
- String currentDirPath = getServletContext().getRealPath(currentPath);
- // 創建當前路徑
- File currentDir = new File(currentDirPath);
- if (!currentDir.exists()) {
- currentDir.mkdir();
- }
- // 創建返回的xml文件
- Document document = null;
- try {
- DocumentBuilderFactory factory = DocumentBuilderFactory
- .newInstance();
- DocumentBuilder builder = factory.newDocumentBuilder();
- document = builder.newDocument();
- } catch (ParserConfigurationException pce) {
- pce.printStackTrace();
- }
- Node root = CreateCommonXml(document, commandStr, typeStr,
- currentFolderStr, request.getContextPath() + currentPath);
- // 得到用戶選擇的目錄
- if (commandStr.equals("GetFolders")) {
- getFolders(currentDir, root, document);
- }
- // 得到用戶選擇的目錄的文件
- else if (commandStr.equals("GetFoldersAndFiles")) {
- getFolders(currentDir, root, document);
- getFiles(currentDir, root, document);
- }
- // 新建的目錄
- else if (commandStr.equals("CreateFolder")) {
- String newFolderStr = request.getParameter("NewFolderName");
- //上傳時,創建文件夾時出現亂碼問題的解決方法
- newFolderStr=new String(newFolderStr.getBytes("iso8859-1"),"UTF-8");
- File newFolder = new File(currentDir, newFolderStr);
- System.out.println(newFolderStr+"文件夾");
- String retValue = "110";
- // 只能輸入英文字符數字或下划線
- if (!(Pattern.matches("\\w+", newFolderStr))) {
- retValue = "102";
- }
- // 目錄已經存在
- else if (newFolder.exists()) {
- retValue = "101";
- }
- // 建立新目錄
- else {
- try {
- boolean dirCreated = newFolder.mkdir();
- if (dirCreated)
- retValue = "0";
- else
- retValue = "102";
- } catch (SecurityException sex) {
- sex.printStackTrace();
- retValue = "103";
- }
- }
- setCreateFolderResponse(retValue, root, document);
- }
- document.getDocumentElement().normalize();
- try {
- TransformerFactory tFactory = TransformerFactory.newInstance();
- Transformer transformer = tFactory.newTransformer();
- DOMSource source = new DOMSource(document);
- StreamResult result = new StreamResult(out);
- transformer.transform(source, result);
- if (debug) {
- StreamResult dbgResult = new StreamResult(System.out);
- transformer.transform(source, dbgResult);
- }
- } catch (Exception ex) {
- // ex.printStackTrace();
- }
- out.flush();
- out.close();
- }
- /**
- * 處理文件上傳
- *
- * 此servlet接收如下參數:
- * connector?Command=FileUpload&Type=ResourceType&CurrentFolder=FolderPath
- */
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/html; charset=UTF-8");
- response.setHeader("Cache-Control", "no-cache");
- PrintWriter out = response.getWriter();
- String commandStr = request.getParameter("Command");
- // 得到文件類型,Image,File,Flash,Media
- String typeStr = request.getParameter("Type");
- // 得到當前目錄
- String currentFolderStr = request.getParameter("CurrentFolder");
- // 得到當前的真實路徑
- String currentPath = baseDir + typeStr + currentFolderStr;
- String currentDirPath = getServletContext().getRealPath(currentPath);
- String retVal = "0";
- String newName = "";
- if (!commandStr.equals("FileUpload"))
- retVal = "203";
- else {
- // 產生的上傳對象,並設置編譯
- DiskFileUpload upload = new DiskFileUpload();
- upload.setHeaderEncoding("UTF-8");
- 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 ext = getExtension(fileName);
- //為防止中文圖片無法正確讀取,在保存前,將圖片名稱改為uuid編碼格式
- fileName=UUID.randomUUID().toString()+"."+ext;
- String nameWithoutExt = getNameWithoutExtension(fileName);
- File pathToSave = new File(currentDirPath, fileName);
- System.out.println("pathToSave"+pathToSave);
- int counter = 1;
- int limitedSize=70*1024;//限制上傳圖片的大小
- // 檢查允許上傳的文件類型是否為Image,是則再檢查文件類型在web.xml配置
- if ((this.checkImageType(allowedType, fileName))
- && (typeStr.equals("Image"))) {
- retVal = "202";
- // System.out.println("dd");
- } else if ((this.checkFileType(unallowedFileType, fileName))
- && (typeStr.equals("File"))) {
- // System.out.println("ddee");
- retVal = "202";
- }
- //如果文件大小超過限制,則返回一個自定義的錯誤碼
- else if(uplFile.getSize()>limitedSize)
- {
- retVal="204";
- }
- else {
- while (pathToSave.exists())
- {
- newName = nameWithoutExt + "(" + counter + ")" + "."
- + ext;
- newName=UUID.randomUUID().toString()+"."+ext;
- retVal = "201";
- pathToSave = new File(currentDirPath, newName);
- counter++;
- System.out.println("namewithoutext:"+nameWithoutExt);
- }
- uplFile.write(pathToSave);
- }
- } catch (Exception ex) {
- ex.printStackTrace();
- retVal = "203";
- }
- }
- // out.println("<SCRIPT type='\"text/javascript\"'>");
- out.print("<mce:script language='javascript'><!--
- window.parent.frames['frmUpload'].OnUploadCompleted("+retVal + ",'" + newName + "');
- // --></mce:script>");
- // out.println("window.parent.frames['frmUpload'].OnUploadCompleted("
- // + retVal + ",'" + newName + "');");
- // out.println("</SCRIPT>");
- // out.flush();
- // out.close();
- }
- private void setCreateFolderResponse(String retValue, Node root,
- Document doc) {
- Element myEl = doc.createElement("Error");
- myEl.setAttribute("number", retValue);
- root.appendChild(myEl);
- }
- private void getFolders(File dir, Node root, Document doc) {
- Element folders = doc.createElement("Folders");
- root.appendChild(folders);
- File[] fileList = dir.listFiles();
- for (int i = 0; i < fileList.length; ++i) {
- if (fileList[i].isDirectory()) {
- Element myEl = doc.createElement("Folder");
- myEl.setAttribute("name", fileList[i].getName());
- folders.appendChild(myEl);
- }
- }
- }
- private void getFiles(File dir, Node root, Document doc) {
- Element files = doc.createElement("Files");
- root.appendChild(files);
- File[] fileList = dir.listFiles();
- for (int i = 0; i < fileList.length; ++i) {
- if (fileList[i].isFile()) {
- Element myEl = doc.createElement("File");
- myEl.setAttribute("name", fileList[i].getName());
- myEl.setAttribute("size", "" + fileList[i].length() / 1024);
- files.appendChild(myEl);
- }
- }
- }
- private Node CreateCommonXml(Document doc, String commandStr,
- String typeStr, String currentPath, String currentUrl) {
- Element root = doc.createElement("Connector");
- doc.appendChild(root);
- root.setAttribute("command", commandStr);
- root.setAttribute("resourceType", typeStr);
- Element myEl = doc.createElement("CurrentFolder");
- myEl.setAttribute("path", currentPath);
- myEl.setAttribute("url", currentUrl);
- root.appendChild(myEl);
- return root;
- }
- /**
- * 得到文件名,沒有擴展名
- *
- *
- *
- * @param fileName
- * @return
- */
- private static String getNameWithoutExtension(String fileName) {
- return fileName.substring(0, fileName.lastIndexOf("."));
- }
- /**
- * 得到文件的擴展名
- *
- * @param fileName
- * @return
- */
- private String getExtension(String fileName) {
- return fileName.substring(fileName.lastIndexOf(".") + 1);
- }
- /**
- * 檢查上傳Image類型的的文件類型,根據在 web.xml配置的信息
- *
- *
- *
- * @param type
- * @param fileName
- * @return
- */
- private boolean checkImageType(String type, String fileName) {
- System.out.println(type+"type");
- String[] ss = type.split("\\|");
- System.out.println(ss+"ss");
- if (type.length() > 0) {
- for (int i = 0; i < ss.length; i++) {
- if (this.getExtension(fileName).equalsIgnoreCase(ss[i])) {
- return false;
- }
- // System.out.println(ss[i]);
- }
- }
- return true;
- }
- /**
- * 驗證不允許上傳的File類型的文件
- *
- *
- * @param type
- * @param fileName
- * @return
- */
- private boolean checkFileType(String type, String fileName) {
- String[] ss = type.split("\\|");
- if (type.length() > 0) {
- for (int i = 0; i < ss.length; i++) {
- if (this.getExtension(fileName).equalsIgnoreCase(ss[i])) {
- return true;
- }
- // System.out.println(ss[i]);
- // System.out.println(fileName);
- }
- }
- return false;
- }
- }