最 近在做一个新闻发布平台,放弃了很早的FCKEditor,使用CKEditor和CKFinder,尽管免费的CKFinder是Demo版本,但是功 能完整,而且用户都是比较集中精神发新闻的人,不会在意这个。按照官网的document一步一步配置,虽然并不难,但是有些东西特别分散,还是全英文 的,所以我就整理了一下安装过程和配置,以及需要注意的一些问题。希望对大家有所帮助。

1. 下载CKEditor相关的安装文件

  • CKEditor: 在 http://ckeditor.com/download 页 面左侧,可以下载到各种版本的CKEditor,包括完整版full、标准版standard、基础版basic等。在页面右侧上方,还有可定制的下载, 可以选择Toolbar类型、插件、语言等。这里我们选择4.1版本的Full版本,下载后得到CKEditor_4.1_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.3.1版本,下载后得到CKFinder_java_2.3.1.zip。

2. 安装CKEditor和CKFinder

  • 解压CKEditor_4.1_full.zip,把解压得到的目录 ckeditor 完全复制到网站根目录下,也就是和WEB-INF同级。可以给这个目录加上版本号,即ckeditor4.1。
  • 把 ckeditor4.1/samples 完全删掉,把 ckeditor4.1/lang 里面除了en.js和zh-cn.js之外的文件删掉,把 ckeditor4.1 下的README.md, CHANGES.md删掉。
  • 把 ckeditor-java-core-3.5.3.jar 放到yourapp/WEB-INF/lib下
  • 解压CKFinder_java_2.3.1.zip,得到ckfinder目录。将 ckfinder/CKFinderJava/ckfinder 目录完全复制到网站根目录下,也就是和WEB-INF同级。可以给这个目录加上版本号,即ckfinder2.3.1。
  • 把 ckfinder2.3.1/_samples完全删掉,把 ckfinder2.3.1/lang 下除了en.js和zh-cn.js之外的文件删掉,把 ckfinder2.3.1 下的changelog.txt,install.txt,license.txt,translations.txt删掉。
  • 把 ckfinder/CKFinderJava/WEB-INF/lib 下所有的jar包复制到yourapp/WEB-INF/lib下。
  • 把 ckfinder/CKFinderJava/WEB-INF/config.xml复制到yourapp/WEB-INF下,并改名为ckfinder.xml。

3. 在网页里使用CKEditor

Step1:找到需要放置CKEditor编辑器的页面,引入CKEditor的js文件(${contextPath}是JSTL写法,请改成你自己的路径写法,绝对路径或者相对路径)

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

Step2:在需要提交的form里,写一个<textarea>

<form id="detailForm" method="post">
<textarea id="content" name="content"></textarea>
<input type="button" value="保存" id="save" onclick="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不存在的错误。上述代码并不是创建CKEditor实例的唯一方法,大家可以自行查阅资料。

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.1/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.1/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>之后不加换行7
});
}
}
});
};
</script>

关于这部分内容,更多内容参看 http://docs.ckeditor.com/#!/guide/dev_output_format

7. 将CKFinder整合进CKEditor

没有CKFinder,CKEditor作为一个编辑器,也是可以正常使用的,但是无法在编辑器里浏览服务器上的用户上传文件。所以要整合CKFinder。

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

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

Step2:创建CKFinder实例

<script type="text/javascript">
var editor = null;
window.onload = function() {
editor = CKEDITOR.replace( 'content', {
customConfig:'${contextPath}/ckeditor4.1/jwc_config.js'
});
CKFinder.setupCKEditor( editor, '${contextPath}/ckfinder2.3.1/' );
};
</script>

上面标红的代码,第一个参数是CKEditor实例,第二个参数是ckfinder的目录(最好写绝对路径),注意最后要带斜杠'/'。

Step3:在CKEditor里配置通过哪个页面或者程序来浏览和上传文件

找到你的项目里配置CKEditor的位置(参看本文CKEditor的三种配置方式部分),配置以下内容:

CKEDITOR.editorConfig = function( config ) {
//其他一些配置
filebrowserBrowseUrl = '/ckfinder2.3.1/ckfinder.html';
filebrowserImageBrowseUrl = '/ckfinder2.3.1/ckfinder.html?type=Images';
filebrowserFlashBrowseUrl = '/ckfinder2.3.1/ckfinder.html?type=Flash';
filebrowserUploadUrl = '/ckfinder2.3.1/core/connector/java/connector.java?command=QuickUpload&type=Files';
filebrowserImageUploadUrl = '/ckfinder2.3.1/core/connector/java/connector.java?command=QuickUpload&type=Images';
filebrowserFlashUploadUrl = '/ckfinder2.3.1/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.3.1/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.3.1/ckfinder.html时(包括点击下图的“浏览服务器”按钮),检查CKFinder_UserRole的值是什么,它具有的权限是什么。如果一个人没有登录系统,而是直接访问yoursite/ckfinder2.3.1/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.3.1/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更安全,当然同时使用会更好。但是注意两者区别,后者只能在比较粗的粒度进行控制。

最新文章

  1. Xms Xmx PermSize MaxPermSize 区别
  2. 使用Mod_JK链接Apache和Tomcat
  3. Java for LeetCode 152 Maximum Product Subarray
  4. JDK和JVM
  5. Spring学习之Ioc控制反转(1)
  6. icpc 南昌邀请赛网络赛 Subsequence
  7. PHP 闭包函数
  8. 【QT】Installer requires Xcode Version 5.0.0 for Qt download if toolchain not found
  9. 【Go】strings.Replace 与 bytes.Replace 调优
  10. VeeamBackup9.5安装与配置
  11. ubuntu6.4系统安装JIRA-7.8
  12. Spring MVC (Java),强制页面不缓存
  13. POJ - 3122 Pie(二分)
  14. centos 编译安装PHP5.4
  15. C# 各类常见Exception 异常信息
  16. redis实战笔记(2)-第2章 使用 Redis构建Web应用
  17. multimap详讲
  18. linq中where与skipwhile区别
  19. dwarf是怎样处理的栈帧?
  20. 编写简单的spring mvc程序,在tomcat上部署

热门文章

  1. AI 人工智能 探索 (二)
  2. JS 的NULL undefined 空
  3. CentOS下Samba服务器的配置
  4. 转:LoadRunner获取毫秒及字符串替换实现
  5. Windows API 之 CreateFile、CreateFileMapping 、MapViewOfFile
  6. LNMPA by lin
  7. cookies和session的优缺点
  8. mongodb从来没有说它写成功了。
  9. javascript的事件冒泡,阻止事件冒泡和事件委托, 事件委托是事件冒泡的一个应用。
  10. maven项目如何跳过某些junit test,或者指定执行部分junit test