ckeditor中“浏览服务器”的后台操作
此博文,基于CKeditor 4.5.6版本测试通过。
原创博文,转载请注明出处
参考官方文档,以及网络上的一些帖子。经过调试得到正确的期待中的结果。
【网络上的一些所谓的帖子,不知道是故意将上传的代码整点错误其中,还是无疑间遗漏了些什么,总之整个看是完整的程序,经过我的仔细研究和debug,存在很多KENG, 我崇尚分享的理念,既然blog出来,就要认真的对网友有所帮助】
这里,简单的贴一下ckeditor的配置:
CKEDITOR.editorConfig = function( config ) {
config.toolbarGroups = [
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] },
{ name: 'forms', groups: [ 'forms' ] },
'/',
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi', 'paragraph' ] },
{ name: 'links', groups: [ 'links' ] },
{ name: 'insert', groups: [ 'insert' ] },
'/',
{ name: 'styles', groups: [ 'styles' ] },
{ name: 'colors', groups: [ 'colors' ] },
{ name: 'tools', groups: [ 'tools' ] },
{ name: 'others', groups: [ 'others' ] }
]; config.removeButtons = 'Source,Save,NewPage,Scayt, About';
config.image_previewText=' '; //预览区域显示内容
config.filebrowserImageBrowseUrl = '/browse/mgmt?type=image';
config.filebrowserImageUploadUrl = '/upload/mgmt?type=image';
};
细心的朋友,可能会发现,这个和我前一篇博文有一点点不同,其实是为了让spring后台程序更加健壮而做了写重构所需的调整。不影响大局。
下面贴出后台的完整代码:
package com.tinguish.mueas.infra.upload; import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import com.tinguish.mueas.constant.FileType;
import com.tinguish.mueas.constant.MueasConstants; /**
* 浏览服务器的文件.
* 目标是做到让用户只能浏览自己曾经上传的问题,不能看别人的文件。
*
*/
@Controller
public class FileBrowerController {
protected final Logger logger = Logger.getLogger(getClass()); private static final String IMAGE_DIR = MueasConstants.FILE_UPLOAD_DIR + MueasConstants.FILE_UPLOAD_SUB_IMG_DIR; private static final String FILE_DIR = MueasConstants.FILE_UPLOAD_DIR + MueasConstants.FILE_UPLOAD_SUB_FILE_DIR; private static final String FLASH_DIR = MueasConstants.FILE_UPLOAD_DIR + MueasConstants.FILE_UPLOAD_SUB_FLASH_DIR; private static final String VIDEO_DIR = MueasConstants.FILE_UPLOAD_DIR + MueasConstants.FILE_UPLOAD_SUB_VIDEO_DIR; @RequestMapping(value = "/browse/mgmt", method = RequestMethod.GET)
public void processBrower(ModelMap modelMap, HttpServletRequest request,
HttpServletResponse response) {
logger.info(System.currentTimeMillis());
processBrowerPost(modelMap, request, response);
return;
} @SuppressWarnings("deprecation")
@RequestMapping(value = "/browse/mgmt", method = RequestMethod.POST)
public void processBrowerPost(ModelMap modelMap, HttpServletRequest request, HttpServletResponse response) { String typeStr = request.getParameter("type");
String floderName = request.getParameter("folder"); if (logger.isDebugEnabled()) {
logger.debug("Browsing files,format: " + typeStr);
} String realPath = "";
if(StringUtils.isNotBlank(floderName)){
floderName = URLDecoder.decode(floderName);
// 如果请求中存在文件夹名称,则定位到文件夹中
realPath = request.getSession().getServletContext().getRealPath(floderName);
if(logger.isInfoEnabled()){
logger.info("Requested folder:" + realPath);
}
}else if(StringUtils.equalsIgnoreCase(typeStr, FileType.IMAGE.name())){
// 如果请求中不存在文件夹名称,则使用默认的文件夹
realPath = request.getSession().getServletContext().getRealPath(MueasConstants.APP_RUNNING_FILES_DIR + IMAGE_DIR);
if(logger.isInfoEnabled()){
logger.info("Default folder:" + realPath);
}
} File folder = new File(realPath);
if(!folder.exists()){
return;
} // 存储子目录
List<String> subFolderSet = new ArrayList<String>();
// 存储文件夹
List<String> subFileerSet = new ArrayList<String>(); File[] subFiles = folder.listFiles();
if(null != subFiles && 0 < subFiles.length){
for(int i=0;i < subFiles.length; i++){
File _file = subFiles[i];
if(_file.isDirectory()){
subFolderSet.add(getDefaultFolderFromMueasRunningData(_file));
} else {
subFileerSet.add(getFileName(_file.getName()));
}
}
} String callback = request.getParameter("CKEditorFuncNum");
PrintWriter out; response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
String outs = "<!DOCTYPE html>"
+ "<html>"
+ "<head>"
+ "<title>服务器文件</title>"
+ "</head>"
+ "<body>";
try {
out = response.getWriter(); outs += "<style type='text/css'>"
+ "li:hover{"
+ " color: #34ac83;"
+ " font-size: 19px;"
+ " cursor: pointer;"
+ "}"
+ "</style>"; outs += "<script type='text/javascript'>"; // 定义点击选择js
String choose = "function choose(obj){"
+ "window.opener.CKEDITOR.tools.callFunction(" + callback + ", obj);"
+ "window.close();"
+"}";
outs += choose;
//logger.info(choose); // 定义文件夹点击响应js
String view = "function view(obj){"
+ "window.location.href='/browse/mgmt?type=image&CKEditorFuncNum=" + callback + "&folder=' + obj;"
+"}";
//logger.info(view);
outs += view;
outs +="</script>"; // 这里显示一个返回顶级目录,也就是返回mueas-running-data目录
String div1 = "<div style='width:100%;float:left;word-break:break-all;' "
+ "onclick =view('" + URLEncoder.encode(MueasConstants.APP_RUNNING_FILES_DIR + MueasConstants.FILE_UPLOAD_DIR) + "')>"
+ "<li>根级目录</li>"
+ "</div>";
//logger.info(div1);
outs += div1; // 如果是子文件夹,显示上级目录链接
if(StringUtils.isNotBlank(floderName) && !checkIsRoot(folder)){
String parent = getDefaultFolderFromMueasRunningData(folder.getParentFile());
String div2 = "<div style='width:100%;float:left;word-break:break-all;' onclick =view('" + URLEncoder.encode(parent) + "')>"
+ "<li>上级目录: "+parent+"</li>"
+ "</div>";
//logger.info(div2);
outs += div2;
if(logger.isDebugEnabled()){
logger.debug("Parent folder exists: " + parent);
}
} // 如果是文件夹,则显示文件夹并且可以再次触发下级和上级目录
if(0 < subFolderSet.size()){
Iterator<String> subFolderSetIndex = subFolderSet.iterator();
while(subFolderSetIndex.hasNext()){
String ftemp = subFolderSetIndex.next();
// 这里url传递的时候,需要转义
String div3 = "<div style='width:100%;float:left;word-break:break-all;' onclick =view('" + URLEncoder.encode(ftemp) + "')>"
+ "<li>下级目录: "+ftemp+"</li>"
+ "</div>";
//logger.info(div3);
outs += div3; if(logger.isDebugEnabled()){
logger.debug("Adding sub folder: "+ftemp);
}
}
} // 如果是文件,则点击就选择文件到控件中
if(0 < subFileerSet.size()){
Iterator<String> subFileerSetIndex = subFileerSet.iterator();
while(subFileerSetIndex.hasNext()){
String ftemp = subFileerSetIndex.next();
String f = getDefaultFolderFromMueasRunningData(folder);
String fileUrl = f + File.separator + ftemp;
fileUrl = StringUtils.replace(fileUrl, "//", "/");
String div4 = "<div style='width:150px;height:150px;float:left;word-break:break-all;padding:5px;background:#666699;margin:5px;'>"
+ "<a href='javascript:void(0)' onclick=choose('"+fileUrl+"')>"
+ "<img style='border:none;width:145px;height:145px;' src='"+fileUrl+"' title='"+fileUrl+"'/>"
+ "</a>"
+ "</div>";
//logger.info(div4);
outs += div4; if(logger.isDebugEnabled()){
logger.debug("Adding file: " + fileUrl);
}
}
}
outs += "</body></html>";
logger.info(outs);
out.println(outs);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 从/mueas-running-data这一级开始获取文件夹路径
* @return
*/
private static String getDefaultFolderFromMueasRunningData(File folder){
String path = folder.getPath();
path = path.substring(path.indexOf(MueasConstants.APP_RUNNING_FILES_DIR));
return path;
} /**
* 判断是否是根目录
* @param floderName
* @return
*/
private static boolean checkIsRoot(File folder){
String name = getFileName(folder.getName());
return StringUtils.equalsIgnoreCase("/" + name, MueasConstants.FILE_UPLOAD_DIR);
} /**
* 获取输入文件路径或者目录路径中最后一级的名字,即可能是一个文件名,也可能是一个子目录的名字
*
* @param file
* @return
*/
private static String getFileName(String file){
String temp = new String(file);
temp = temp.replace("//", "/");
String items[] = file.split("/");
if(items.length > 0){
return items[items.length - 1];
}else{
return null;
}
}
}
这其中,需要细心的是动态创建的html文件,我在这里遇到了些小问题,主要是字符串拼接时格式的问题。这些,通过打印日志,还是比较容易看出来的!
最后,上一下测试效果图片:
点击上面鼠标所在位置的子目录后,得到下面的图片:
欢迎拍砖。
ckeditor中“浏览服务器”的后台操作的更多相关文章
- ruby -- 进阶学习(十六)ckeditor去除“浏览服务器”按钮
FROM:http://blog.163.com/zjc_8886/blog/static/2408175201011222590967/ 实现方法: 由于ckeditor中的"上传图片& ...
- CKEditor禁用浏览服务器的功能
在CKeditor的config.js文件中,添加以下内容,重启服务器,图片.flash.video中的浏览服务器按钮就会消失掉 /*按下" 浏览服务器"按钮时应启动的外部文件管理 ...
- AngularJs调用NET MVC 控制器中的函数进行后台操作
题目中提到的控制器指的是.NET MVC的控制器,不是angularjs的控制器. 首先看主页面的代码: <!DOCTYPE html> <html> <head> ...
- MFC程序执行后台操作时不允许操作界面的一种方法
在使用MFC编写界面程序时,有时候会遇到像点击按钮后,后台进行大量操作后才显示处理结果这种情况,在后台处理过程中,界面不应该被允许做任何操作,这里介绍一种方法. 解决办法 点击按钮后,弹出一个模态对话 ...
- 通过使用Web Workers,Web应用程序可以在独立于主线程的后台线程中,运行一个脚本操作。这样做的好处是可以在独立线程中执行费时的处理任务,从而允许主线程(通常是UI线程)不会因此被阻塞/放慢。
Web Workers API - Web API 接口参考 | MDNhttps://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API ...
- CKEditor4.7怎样实现上传图片,浏览服务器(无需ckfinder),nodejs图片管理,字体居中,图片居中(超详细)
首先是下载CKEditor,下载地址:http://ckeditor.com/download 选择里面的Customize自定义,如图 然后进入配置界面,第一个choose preset一般就选st ...
- YII2 实现后台操作记录日志(转)
一.连接linux服务器,创建数据文件 php yii migrate/create user_log 二.修改数据文件 console/migrations/m150721_032220_admin ...
- atitit. web 在线文件管理器最佳实践(1)--- elFinder 的使用流程解决之道 。打开浏览服务器文件夹java .net php
atitit. web 在线文件管理器最佳实践(1)--- elFinder 的使用流程解决之道 .打开浏览服务器文件夹java .net php 1. 环境:::项目java web,需要打开浏览服 ...
- YII2 实现后台操作记录日志
一.连接linux服务器,创建数据文件 php yii migrate/create user_log 二.修改数据文件 console/migrations/m150721_032220_admin ...
随机推荐
- Oracle PL/SQL高级应用 视图 同义词 序列
视图: 视图叫虚表,即是在哪个表上建立的视图,将那个表的数据用一条查询sql语句查出的数据展现在该视图中,对这个视图操作就是只能对该视图中的数据进行操作,该操作也会保存在建立的表中.可以理解为表上表, ...
- cocos2d-html5如何更改预加载时的默认的logo图片和删除loading小圈圈
找到框架目录(2.1.4)里的cocos2d目录里有个CCLoader.js文件,找到LoaderScene的构造方法ctor,可以看到有一行: this._logoTexture.src= &quo ...
- bedtools 每天都会用到的工具
详细的使用说明:http://bedtools.readthedocs.org/en/latest/ Collectively, the bedtools utilities are a swiss- ...
- winrar在右键菜单上加上:打包自动加上日期时间标签【图文教程】 - imsoft.cnblogs
说明: 注册表HKEY_CURRENT_USER\Software\WinRAR\Profiles\0找到GenerateArcName修改0为1,修改GenerateMask为你想要的日期式(默认 ...
- poi 合并单元格 无边框问题
public void merge(int startrow,int endstartrow,int startColumn,int endColumn){ sht.addMergedRegion(n ...
- UVA 11997 STL 优先队列
题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- STL概述
一.关于STL STL(Standard Template Library,标准模板库)是C++语言标准中的重要组成部分.STL 以模板类和模板函数的形式为程序员提供了各种数据结构和算法的精巧实现,程 ...
- php随笔杂记(一)
1.在function updatepwd($postData=array()) 如果参数是一个数组, 在使用时,如果给他赋值则只返回数组名$postData即可 ,如果里面已有值 ,这返回的可 ...
- timus 1022 Genealogical Tree(拓扑排序)
Genealogical Tree Time limit: 1.0 secondMemory limit: 64 MB Background The system of Martians’ blood ...
- android开源项目---tool篇
本文转载于:http://blog.csdn.net/likebamboo/article/details/19080801 主要包括那些不错的开发库,包括依赖注入框架.图片缓存.网络相关.数据库OR ...