本文介绍2种使用ckeditor上传文件保存至项目外(即硬盘)的方法。
环境:tomcat + spring
第一种:通过ckeditor+ckfinder搭配。
1)在页面中的配置
引入标签<%@ include file="/WEB-INF/jsp/layouts/taglib_ck.jsp"%>
页面html代码
<textarea name="content" id="content" rows="30"></textarea> <hs:ckeditor replace="content" uploadPath="/cms/content" />
taglib_ck.jsp的内容如下:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <c:set var="ctx" value="${pageContext.request.contextPath}"/> <c:set var="ctxStatic" value="${pageContext.request.contextPath}/scripts"/>
ckeditor.tag的标签如下:
<%@ tag language="java" pageEncoding="UTF-8"%> <%@ include file="/WEB-INF/jsp/layouts/taglib_ck.jsp"%> <%@ attribute name="replace" type="java.lang.String" required="true" description="需要替换的textarea编号"%> <%@ attribute name="uploadPath" type="java.lang.String" required="false" description="文件上传路径,路径后自动添加年份。若不指定,则编辑器不可上传文件"%> <script type="text/javascript">include('ckeditor_lib','${ctxStatic}/ckeditor/',['ckeditor.js']);</script> <script type="text/javascript"> var ${replace}Ckeditor = CKEDITOR.replace("${replace}");//<c:if test="${not empty uploadPath}"> ${replace}Ckeditor.config.ckfinderPath="${ctxStatic}/ckfinder"; var date = new Date(), year = date.getFullYear(), month = (date.getMonth()+1)>9?date.getMonth()+1:"0"+(date.getMonth()+1); ${replace}Ckeditor.config.ckfinderUploadPath="${uploadPath}/"+year+"/"+month+"/";//</c:if> </script>
ckfinder.tag的代码如下:
<%@ tag language="java" pageEncoding="UTF-8"%> <%@ include file="/WEB-INF/jsp/layouts/taglib_ck.jsp"%> <%@ attribute name="input" type="java.lang.String" required="true" description="输入框"%> <%@ attribute name="type" type="java.lang.String" required="true" description="files、images、flash、thumb"%> <%@ attribute name="uploadPath" type="java.lang.String" required="true" description="打开文件管理的上传路径"%> <%@ attribute name="selectMultiple" type="java.lang.Boolean" required="false" description="是否允许多选"%> <ol id="${input}Preview"></ol><a href="javascript:" onclick="${input}FinderOpen();" class="btn">${selectMultiple?'添加':'选择'}</a> <a href="javascript:" onclick="${input}DelAll();" class="btn">清除</a> <script type="text/javascript"> function ${input}FinderOpen(){//<c:if test="${type eq 'thumb'}"><c:set var="ctype" value="images"/></c:if><c:if test="${type ne 'thumb'}"><c:set var="ctype" value="${type}"/></c:if> var date = new Date(), year = date.getFullYear(), month = (date.getMonth()+1)>9?date.getMonth()+1:"0"+(date.getMonth()+1); var url = "${ctxStatic}/ckfinder/ckfinder.html?type=${ctype}&start=${ctype}:${uploadPath}/"+year+"/"+month+ "/&action=js&func=${input}SelectAction&thumbFunc=${input}ThumbSelectAction&cb=${input}Callback&dts=${type eq 'thumb'?'1':'0'}&sm=${selectMultiple?1:0}"; windowOpen(url,"文件管理",1000,700); //top.$.jBox("iframe:"+url+"&pwMf=1", {title: "文件管理", width: 1000, height: 500, buttons:{'关闭': true}}); } function ${input}SelectAction(fileUrl, data, allFiles){ var url="", files=ckfinderAPI.getSelectedFiles(); for(var i=0; i<files.length; i++){//<c:if test="${type eq 'thumb'}"> url += files[i].getThumbnailUrl();//</c:if><c:if test="${type ne 'thumb'}"> url += files[i].getUrl();//</c:if> if (i<files.length-1) url+="|"; }//<c:if test="${selectMultiple}"> $("#${input}").val($("#${input}").val()+($("#${input}").val(url)==""?url:"|"+url));//</c:if><c:if test="${!selectMultiple}"> $("#${input}").val(url);//</c:if> ${input}Preview(); //top.$.jBox.close(); } function ${input}ThumbSelectAction(fileUrl, data, allFiles){ var url="", files=ckfinderAPI.getSelectedFiles(); for(var i=0; i<files.length; i++){ url += files[i].getThumbnailUrl(); if (i<files.length-1) url+="|"; }//<c:if test="${selectMultiple}"> $("#${input}").val($("#${input}").val()+($("#${input}").val(url)==""?url:"|"+url));//</c:if><c:if test="${!selectMultiple}"> $("#${input}").val(url);//</c:if> ${input}Preview(); //top.$.jBox.close(); } function ${input}Callback(api){ ckfinderAPI = api; } function ${input}Del(obj){ var url = $(obj).prev().attr("url"); $("#${input}").val($("#${input}").val().replace("|"+url,"","").replace(url+"|","","").replace(url,"","")); ${input}Preview(); } function ${input}DelAll(){ $("#${input}").val(""); ${input}Preview(); } function ${input}Preview(){ var li, urls = $("#${input}").val().split("|"); $("#${input}Preview").children().remove(); for (var i=0; i<urls.length; i++){ if (urls[i]!=""){//<c:if test="${type eq 'thumb' || type eq 'images'}"> li = "<li><img src=\""+urls[i]+"\" url=\""+urls[i]+"\" style=\"max-width:200px;max-height:200px;_height:200px;border:0;padding:3px;\">";//</c:if><c:if test="${type ne 'thumb' && type ne 'images'}"> li = "<li><a href=\""+urls[i]+"\" url=\""+urls[i]+"\" target=\"_blank\">"+decodeURIComponent(urls[i].substring(urls[i].lastIndexOf("/")+1))+"</a>";//</c:if> li += " <a href=\"javascript:\" onclick=\"${input}Del(this);\">×</a></li>"; $("#${input}Preview").append(li); } } } ${input}Preview(); </script>
最主要的一个引入js的方法:在ckeditor.tag中调用
function include(id, path, file) { if (document.getElementById(id) == null) { var files = typeof file == "string" ? [ file ] : file; for ( var i = 0; i < files.length; i++) { var name = files[i].replace(/^\s|\s$/g, ""); var att = name.split('.'); var ext = att[att.length - 1].toLowerCase(); var isCSS = ext == "css"; var tag = isCSS ? "link" : "script"; var attr = isCSS ? " type='text/css' rel='stylesheet' " : " type='text/javascript' "; var link = (isCSS ? "href" : "src") + "='" + path + name + "'"; document.write("<" + tag + (i == 0 ? " id=" + id : "") + attr + link + "></" + tag + ">"); } } }
2)在ckeditor config中配置上传 ---基于ckfinder自身的上传
CKEDITOR.editorConfig = function( config ) { config.language = 'zh-cn'; config.uiColor = '#f7f5f4'; //config.skin="v2"; config.width = '99.7%'; config.height = '300px'; config.removePlugins = 'elementspath,scayt'; config.disableNativeSpellChecker = false; config.resize_dir = 'vertical'; config.keystrokes =[[ CKEDITOR.CTRL + 13 /*Enter*/, 'maximize' ]]; config.extraPlugins = 'tableresize'; config.enterMode = CKEDITOR.ENTER_P; config.shiftEnterMode = CKEDITOR.ENTER_BR; config.font_names='宋体/宋体;黑体/黑体;仿宋/仿宋_GB2312;楷体/楷体_GB2312;隶书/隶书;幼圆/幼圆;微软雅黑/微软雅黑;'+ config.font_names; config.image_previewText=' '; config.toolbar_default = [ ['Source'], ['Cut','Copy','Paste','PasteText','PasteFromWord','Undo','Redo'], ['Link','Unlink','Anchor'], ['Image','Flash','Table','HorizontalRule','SpecialChar','Smiley'], ['Maximize'], '/', ['Bold','Italic','Underline','Strike','RemoveFormat'], ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['Styles','Font','FontSize'], ['TextColor','BGColor'] ]; config.toolbar = 'default'; if(config.ckfinderPath){ config.filebrowserBrowseUrl = config.ckfinderPath+'/ckfinder.html?type=files'; config.filebrowserImageBrowseUrl = config.ckfinderPath+'/ckfinder.html?type=images'; config.filebrowserFlashBrowseUrl = config.ckfinderPath+'/ckfinder.html?type=flash'; config.filebrowserUploadUrl = config.ckfinderPath+'/core/connector/java/connector.java?command=QuickUpload&type=files'; config.filebrowserImageUploadUrl = config.ckfinderPath+'/core/connector/java/connector.java?command=QuickUpload&type=images'; config.filebrowserFlashUploadUrl = config.ckfinderPath+'/core/connector/java/connector.java?command=QuickUpload&type=flash'; config.filebrowserWindowWidth = '1000'; config.filebrowserWindowHeight = '700'; } }; CKEDITOR.stylesSet.add( 'default', [ /* Block Styles */ { name : '首行缩进' , element : 'p', styles : { 'text-indent' : '20pt' } }, /* Inline Styles */ { name : '标注黄色' , element : 'span', styles : { 'background-color' : 'Yellow' } }, { name : '标注绿色' , element : 'span', styles : { 'background-color' : 'Lime' } }, /* Object Styles */ { name : '图片左对齐', element : 'img', attributes : { 'style' : 'padding: 5px; margin-right: 5px', 'border' : '2', 'align' : 'left' } }, { name : '图片有对齐', element : 'img', attributes : { 'style' : 'padding: 5px; margin-left: 5px', 'border' : '2', 'align' : 'right' } }, { name : '无边界表格', element : 'table', styles: { 'border-style': 'hidden', 'background-color' : '#E6E6FA' } } ]);
3)将ckfinder.xml放入WEB-INF目录下
4)在web.xml中配置ckfinder
<!-- CKFinder 编辑器可上传图片附件 --> <servlet> <servlet-name>CKFinderConnectorServlet</servlet-name> <servlet-class>hs.ckeditor.CKFinderConnectorServlet</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> <init-param> <param-name>configuration</param-name> <param-value>hs.ckeditor.CKFinderConfig</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CKFinderConnectorServlet</servlet-name> <url-pattern>/scripts/ckfinder/core/connector/java/connector.java</url-pattern> </servlet-mapping> <filter> <filter-name>FileUploadFilter</filter-name> <filter-class>com.ckfinder.connector.FileUploadFilter</filter-class> <init-param> <param-name>sessionCookieName</param-name> <param-value>JSESSIONID</param-value> </init-param> <init-param> <param-name>sessionParameterName</param-name> <param-value>jsessionid</param-value> </init-param> </filter> <filter-mapping> <filter-name>FileUploadFilter</filter-name> <url-pattern>/scripts/ckfinder/core/connector/java/connector.java</url-pattern> </filter-mapping>
其中hs.ckeditor.CKFinderConfig 需要自己定义。
CKFinderConfig.java
import javax.servlet.ServletConfig; import javax.servlet.http.HttpServletRequest; import com.ckfinder.connector.ServletContextFactory; import com.ckfinder.connector.configuration.Configuration; import com.ckfinder.connector.utils.AccessControlUtil; /** * CKFinder配置 * @author selina * @version 2013-08-06 */ public class CKFinderConfig extends Configuration { public CKFinderConfig(ServletConfig servletConfig) { super(servletConfig); } @Override protected Configuration createConfigurationInstance() { AccessControlUtil.getInstance(this).loadACLConfig(); try { this.baseURL = ServletContextFactory.getServletContext().getContextPath()+"/userfiles/" +"/"; } catch (Exception e) { throw new RuntimeException(e); } return new CKFinderConfig(this.servletConf); } @Override public boolean checkAuthentication(final HttpServletRequest request) { //权限验证 return true; } }
CKFinderConnectorServlet.java
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ckfinder.connector.ConnectorServlet; /** * CKFinderConnectorServlet * @author selina * @version 2013-08-06 */ public class CKFinderConnectorServlet extends ConnectorServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { prepareGetResponse(request, response, false); super.doGet(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { prepareGetResponse(request, response, true); super.doPost(request, response); } private void prepareGetResponse(final HttpServletRequest request, final HttpServletResponse response, final boolean post) throws ServletException { String command = request.getParameter("command"); String type = request.getParameter("type"); // 初始化时,如果startupPath文件夹不存在,则自动创建startupPath文件夹 if ("Init".equals(command)){ String startupPath = request.getParameter("startupPath");// 当前文件夹可指定为模块名 if (startupPath!=null){ String[] ss = startupPath.split(":"); if (ss.length==2){ String path = "/userfiles/"+ss[0]+ss[1]; String realPath = request.getSession().getServletContext().getRealPath(path); FileUtils.createDirectory(realPath); } } } // 快捷上传,自动创建当前文件夹,并上传到该路径 else if ("QuickUpload".equals(command) && type!=null){ String currentFolder = request.getParameter("currentFolder");// 当前文件夹可指定为模块名 String path = "/userfiles/"+type+(currentFolder!=null?currentFolder:""); String realPath = request.getSession().getServletContext().getRealPath(path); FileUtils.createDirectory(realPath); } // System.out.println("------------------------"); // for (Object key : request.getParameterMap().keySet()){ // System.out.println(key + ": " + request.getParameter(key.toString())); // } } }
总的来说就是这些了。
总结:通过结合ckeditor与ckfinder可实现编辑器文件上传并且还提供文件夹供浏览,不过这样设置会把文件等保存在项目内,如果文件过多,就会导致资源过多且不易安装与维护。
其实呢,ckfinder也是比较强大的,通过配置ckfinder.xml中的BaseDir也可以实现把文件保存在项目外的功能。不过要在tomcat配置虚拟路径。说明如下:
#当ckfinder.xml中配置了baseDir路径时,附件保存在项目外。不配置时默认在项目内。 当ckfinder.xml配置如下时: <baseDir>d:/xxAttacm/userfiles/</baseDir> <baseURL>/userfiles/</baseURL> 必须在tomcat server.xml下建立虚拟路径如下: 在<Host></Host>之间加入<Context docBase="d:\xxAttacm\userfiles\" path="/myProject/userfiles" reloadable="true"/> 其中myProject为项目发布根目录。docBase需与baseDir对应。
因该文章过长,为不影响浏览效果,第二种方式《CKEditor文件上传-多种方式-自定义上传-保存在项目外》
将在后续补上。如有不足,欢迎指正!
相关推荐
而CKFinder则是一款文件管理器,用于在网页上上传、下载、预览和管理文件,它与CKEditor结合,可以方便地在编辑器中插入图片、文档等多媒体资源。 CKEditor的核心特点包括: 1. **易用性**:CKEditor设计简洁,界面...
Ckeditor和ckFinder是两个在Web开发中广泛使用的工具,尤其在创建富文本编辑器和管理文件上传方面。本文将详细介绍如何在Java环境中整合这两个工具,以实现一个功能完善的文本编辑器,并支持文件上传。 **Ckeditor...
1. **CKFinder 功能**:CKFinder是一款Web文件管理器,提供文件上传、删除、重命名、移动和复制等功能。它支持多种文件类型,包括图像、视频、文档等,且与CKEditor无缝集成,方便在编辑器中插入媒体资源。 2. **...
与ckeditor相辅相成的是`ckfinder`,这是一款用于图像和文件管理的工具,专为ckeditor设计。ckfinder允许用户方便地上传、浏览、管理、删除服务器上的文件和图片,为ckeditor提供了一个直观的媒体库。ckfinder支持多...
CKFinder 是一个用于管理文件和图像的 Web 文件管理器,它可以与 CKEditor 配合使用,提供文件上传、浏览、删除等功能。在 CKFinder 中,用户可以方便地选择本地文件上传到服务器,然后在 CKEditor 中直接插入这些...
将CKEditor与CKFinder结合使用时,首先需要在服务器上安装并配置CKFinder,然后在CKEditor中集成CKFinder的接口。这通常涉及到在CKEditor的配置文件中添加CKFinder的路径,以及设置访问CKFinder所需的参数。一旦集成...
在这个场景中,"JSP使用ckeditor和ckfinder实现富文本及文件上传"是一个常见的需求,尤其是在构建内容管理系统或者论坛等需要用户编辑和上传内容的Web应用中。 ckeditor是一款流行的开源JavaScript富文本编辑器,它...
CKFinder与CKEditor结合使用时,可以在CKEditor中方便地插入、修改或删除图片和其他文件。在本压缩包中,CKFinder 2.1的jar文件是实现这一功能的关键。 除了这两个主要组件,压缩包还包含了一些依赖库,如: 1. `...
在“CKEditor整合上传图片功能”中,我们主要关注的是如何将CKEditor与CKFinder结合,实现图片的上传和管理功能。 CKFinder是一款强大的文件管理器,特别适合与CKEditor搭配使用。它提供了文件浏览、上传、下载、...
将这两者结合,可以创建出一个集文本编辑、文件上传于一体的Web应用,特别适合新闻发布系统、论坛、博客等需要频繁编辑和管理内容的平台。 具体实现时,首先需要在服务器上部署ckeditor和ckFinder,并配置ckFinder...
在上传图片方面,CKEditor和Ckfinder结合使用,提供了无缝的用户体验。用户在CKEditor中选择插入图片后,会调用Ckfinder,用户可以在弹出的窗口中浏览服务器上的图片,或者选择上传新的图片。上传过程通常涉及文件的...
CKFinder是一款文件管理器,它与CKEditor结合,允许用户在编辑内容时方便地上传、管理和删除图片、文件等资源。CKFinder提供了直观的文件浏览界面,支持多种文件类型,包括图像、文档、视频等,并且可以通过配置设置...
CKEditor是一款强大的富文本编辑器,而CKFinder则是一个文件管理器,两者结合可以提供图片、文件上传和管理的能力。以下将详细介绍如何将CKEditor 4.2与CKFinder整合到一起,以及在VS2010环境下进行这个过程的关键...
CKFinder是一款功能强大的文件管理工具,专为网页编辑器如CKEditor设计,提供方便的前台文件上传和管理功能。这款插件使得用户无需后端服务器交互就能直接在前端完成文件和图片的上传操作,极大地提升了用户体验。 ...
在ASP.NET环境中,将CKEditor和CKFinder结合使用,开发者需要做以下几件事: 1. 下载并安装CKEditor和CKFinder:首先,从官方网站下载这两个组件的最新版本,然后按照官方文档的指示进行安装。 2. 集成CKFinder:...
CKFinder则是一个配套的文件管理器,主要用于处理CKEditor中插入的图片、文件等资源的上传、管理和删除。将这两者结合使用,可以构建一个强大的内容管理系统,尤其适用于需要用户编辑和发布包含多媒体元素的文章或...
首先,CKEditor是一个开源的JavaScript富文本编辑器,它提供了多种预设样式和编辑选项,如字体、字号、颜色、对齐方式等,使得用户可以在网页上进行类似Word的文本编辑。CKFinder则是一个与CKEditor配套的文件管理器...
CKEditor是一款强大的富文本编辑器,而CKFinder则是一个文件管理器,两者结合可以提供完整的文本编辑与文件上传功能。 **CKEditor 3.6** CKEditor 3.6是CKEditor的一个旧版本,但它在当时提供了许多先进的特性。这...
CKEditor的核心功能在于提供了一个类似于桌面应用的文本编辑体验,它支持多种格式的文本排版,包括字体、颜色、大小、对齐方式等,还具备插入图片、链接、表格、视频等多媒体元素的能力。CKEditor的可定制性极强,...
ASP.NET MVC4/5是微软开发的一个用于构建动态网站的框架,它结合了MVC(模型-视图-控制器)设计模式和ASP.NET的优势,提供了更灵活、可测试的Web应用开发方式。CKEditor和CKFinder是两个常用的Web富文本编辑器组件,...