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;
- }
- }