SHIHUC

好记性不如烂笔头,还可以分享给别人看看! 专注基础算法,互联网架构,人工智能领域的技术实现和应用。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

ckeditor中“浏览服务器”的后台操作

Posted on 2016-01-06 16:15  shihuc  阅读(1787)  评论(0编辑  收藏  举报

此博文,基于CKeditor 4.5.6版本测试通过。

原创博文,转载请注明出处

参考官方文档,以及网络上的一些帖子。经过调试得到正确的期待中的结果。

【网络上的一些所谓的帖子,不知道是故意将上传的代码整点错误其中,还是无疑间遗漏了些什么,总之整个看是完整的程序,经过我的仔细研究和debug,存在很多KENG, 我崇尚分享的理念,既然blog出来,就要认真的对网友有所帮助】

 

这里,简单的贴一下ckeditor的配置:

 1 CKEDITOR.editorConfig = function( config ) {
 2     config.toolbarGroups = [
 3         { name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
 4         { name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
 5         { name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] },
 6         { name: 'forms', groups: [ 'forms' ] },
 7         '/',
 8         { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
 9         { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi', 'paragraph' ] },
10         { name: 'links', groups: [ 'links' ] },
11         { name: 'insert', groups: [ 'insert' ] },
12         '/',
13         { name: 'styles', groups: [ 'styles' ] },
14         { name: 'colors', groups: [ 'colors' ] },
15         { name: 'tools', groups: [ 'tools' ] },
16         { name: 'others', groups: [ 'others' ] }
17     ];
18 
19     config.removeButtons = 'Source,Save,NewPage,Scayt, About';
20     config.image_previewText=' ';     //预览区域显示内容
21     config.filebrowserImageBrowseUrl = '/browse/mgmt?type=image';
22     config.filebrowserImageUploadUrl = '/upload/mgmt?type=image';    
23 };

细心的朋友,可能会发现,这个和我前一篇博文有一点点不同,其实是为了让spring后台程序更加健壮而做了写重构所需的调整。不影响大局。

 

下面贴出后台的完整代码:

  1 package com.tinguish.mueas.infra.upload;
  2 
  3 import java.io.File;
  4 import java.io.IOException;
  5 import java.io.PrintWriter;
  6 import java.net.URLDecoder;
  7 import java.net.URLEncoder;
  8 import java.util.ArrayList;
  9 import java.util.Iterator;
 10 import java.util.List;
 11 
 12 import javax.servlet.http.HttpServletRequest;
 13 import javax.servlet.http.HttpServletResponse;
 14 
 15 import org.apache.commons.lang3.StringUtils;
 16 import org.apache.log4j.Logger;
 17 import org.springframework.stereotype.Controller;
 18 import org.springframework.ui.ModelMap;
 19 import org.springframework.web.bind.annotation.RequestMapping;
 20 import org.springframework.web.bind.annotation.RequestMethod;
 21 
 22 import com.tinguish.mueas.constant.FileType;
 23 import com.tinguish.mueas.constant.MueasConstants;
 24 
 25 /**
 26  * 浏览服务器的文件.
 27  * 目标是做到让用户只能浏览自己曾经上传的问题,不能看别人的文件。 
 28  * 
 29  */
 30 @Controller
 31 public class FileBrowerController {
 32     protected final Logger logger = Logger.getLogger(getClass());
 33     
 34     private static final String IMAGE_DIR = MueasConstants.FILE_UPLOAD_DIR + MueasConstants.FILE_UPLOAD_SUB_IMG_DIR;
 35     
 36     private static final String FILE_DIR = MueasConstants.FILE_UPLOAD_DIR + MueasConstants.FILE_UPLOAD_SUB_FILE_DIR;
 37     
 38     private static final String FLASH_DIR = MueasConstants.FILE_UPLOAD_DIR + MueasConstants.FILE_UPLOAD_SUB_FLASH_DIR;
 39     
 40     private static final String VIDEO_DIR = MueasConstants.FILE_UPLOAD_DIR + MueasConstants.FILE_UPLOAD_SUB_VIDEO_DIR;
 41 
 42 
 43     @RequestMapping(value = "/browse/mgmt", method = RequestMethod.GET)
 44     public void processBrower(ModelMap modelMap, HttpServletRequest request,
 45             HttpServletResponse response) {
 46         logger.info(System.currentTimeMillis());
 47         processBrowerPost(modelMap, request, response);
 48         return;
 49     }
 50 
 51     @SuppressWarnings("deprecation")
 52     @RequestMapping(value = "/browse/mgmt", method = RequestMethod.POST)
 53     public void processBrowerPost(ModelMap modelMap, HttpServletRequest request, HttpServletResponse response) {
 54 
 55         String typeStr = request.getParameter("type");
 56         String floderName = request.getParameter("folder");
 57         
 58         if (logger.isDebugEnabled()) {
 59             logger.debug("Browsing files,format: " + typeStr);
 60         }
 61 
 62         
 63         String realPath = "";
 64         if(StringUtils.isNotBlank(floderName)){
 65             floderName = URLDecoder.decode(floderName);
 66             // 如果请求中存在文件夹名称,则定位到文件夹中
 67             realPath = request.getSession().getServletContext().getRealPath(floderName);
 68             if(logger.isInfoEnabled()){
 69                 logger.info("Requested folder:" + realPath);
 70             }
 71         }else if(StringUtils.equalsIgnoreCase(typeStr, FileType.IMAGE.name())){
 72             // 如果请求中不存在文件夹名称,则使用默认的文件夹
 73             realPath = request.getSession().getServletContext().getRealPath(MueasConstants.APP_RUNNING_FILES_DIR + IMAGE_DIR);
 74             if(logger.isInfoEnabled()){
 75                 logger.info("Default folder:" + realPath);
 76             }
 77         }
 78         
 79         File folder = new File(realPath);
 80         if(!folder.exists()){
 81             return;
 82         }
 83         
 84         // 存储子目录 
 85         List<String> subFolderSet = new ArrayList<String>();
 86         // 存储文件夹
 87         List<String> subFileerSet = new ArrayList<String>();
 88         
 89         File[] subFiles = folder.listFiles();
 90         if(null != subFiles && 0 < subFiles.length){
 91             for(int i=0;i < subFiles.length; i++){
 92                 File _file = subFiles[i];
 93                 if(_file.isDirectory()){
 94                     subFolderSet.add(getDefaultFolderFromMueasRunningData(_file));
 95                 } else {
 96                     subFileerSet.add(getFileName(_file.getName()));
 97                 }
 98             }
 99         }
100         
101         String callback = request.getParameter("CKEditorFuncNum");
102         PrintWriter out;
103         
104         response.setContentType("text/html");
105         response.setCharacterEncoding("UTF-8");
106         String outs = "<!DOCTYPE html>"
107                       + "<html>"
108                       + "<head>"
109                       + "<title>服务器文件</title>"
110                       + "</head>"
111                       + "<body>";
112         try {
113             out = response.getWriter();
114             
115             outs += "<style type='text/css'>"
116                     + "li:hover{"
117                     + "    color: #34ac83;"
118                     + "    font-size: 19px;"
119                     + " cursor: pointer;"
120                     + "}"
121                     + "</style>";
122             
123             outs += "<script type='text/javascript'>";
124             
125             // 定义点击选择js
126             String choose = "function choose(obj){" 
127                             + "window.opener.CKEDITOR.tools.callFunction(" + callback    + ", obj);" 
128                             + "window.close();" 
129                             +"}";
130             outs += choose;
131             //logger.info(choose);
132             
133             // 定义文件夹点击响应js
134             String view = "function view(obj){"
135                           + "window.location.href='/browse/mgmt?type=image&CKEditorFuncNum=" + callback + "&folder=' + obj;"
136                           +"}";
137             //logger.info(view);
138             outs += view;        
139             outs +="</script>";
140             
141             // 这里显示一个返回顶级目录,也就是返回mueas-running-data目录
142             String div1 = "<div style='width:100%;float:left;word-break:break-all;' "
143                     + "onclick =view('" + URLEncoder.encode(MueasConstants.APP_RUNNING_FILES_DIR + MueasConstants.FILE_UPLOAD_DIR) + "')>"
144                     + "<li>根级目录</li>"
145                     + "</div>";
146             //logger.info(div1);
147             outs += div1;
148             
149             // 如果是子文件夹,显示上级目录链接
150             if(StringUtils.isNotBlank(floderName) && !checkIsRoot(folder)){
151                 String parent = getDefaultFolderFromMueasRunningData(folder.getParentFile());
152                 String div2 = "<div style='width:100%;float:left;word-break:break-all;' onclick =view('" + URLEncoder.encode(parent) + "')>"
153                         + "<li>上级目录: "+parent+"</li>"
154                         + "</div>";    
155                 //logger.info(div2);
156                 outs += div2;
157                 if(logger.isDebugEnabled()){
158                     logger.debug("Parent folder exists: " + parent);
159                 }
160             }
161             
162             // 如果是文件夹,则显示文件夹并且可以再次触发下级和上级目录
163             if(0 < subFolderSet.size()){
164                 Iterator<String> subFolderSetIndex = subFolderSet.iterator();
165                 while(subFolderSetIndex.hasNext()){
166                     String ftemp = subFolderSetIndex.next();
167                     // 这里url传递的时候,需要转义
168                     String div3 = "<div style='width:100%;float:left;word-break:break-all;' onclick =view('" + URLEncoder.encode(ftemp) + "')>"
169                             + "<li>下级目录: "+ftemp+"</li>"
170                             + "</div>";
171                     //logger.info(div3);
172                     outs += div3;
173                     
174                     if(logger.isDebugEnabled()){
175                         logger.debug("Adding sub folder: "+ftemp);
176                     }
177                 }
178             }
179             
180             // 如果是文件,则点击就选择文件到控件中
181             if(0 < subFileerSet.size()){
182                 Iterator<String> subFileerSetIndex = subFileerSet.iterator();
183                 while(subFileerSetIndex.hasNext()){
184                     String ftemp = subFileerSetIndex.next();
185                     String f = getDefaultFolderFromMueasRunningData(folder);
186                     String fileUrl = f + File.separator + ftemp;
187                     fileUrl = StringUtils.replace(fileUrl, "//", "/");
188                     String div4 = "<div style='width:150px;height:150px;float:left;word-break:break-all;padding:5px;background:#666699;margin:5px;'>"
189                             + "<a href='javascript:void(0)' onclick=choose('"+fileUrl+"')>"
190                             + "<img style='border:none;width:145px;height:145px;' src='"+fileUrl+"' title='"+fileUrl+"'/>"
191                             + "</a>"
192                             + "</div>";    
193                     //logger.info(div4);
194                     outs += div4;
195                     
196                     if(logger.isDebugEnabled()){
197                         logger.debug("Adding file: " + fileUrl);
198                     }
199                 }
200             }    
201             outs += "</body></html>";
202             logger.info(outs);
203             out.println(outs);
204             out.flush();
205             out.close();
206         } catch (IOException e) {
207             e.printStackTrace();
208         }
209     }
210     
211     /**
212      * 从/mueas-running-data这一级开始获取文件夹路径
213      * @return
214      */
215     private static String getDefaultFolderFromMueasRunningData(File folder){
216         String path = folder.getPath();
217         path = path.substring(path.indexOf(MueasConstants.APP_RUNNING_FILES_DIR));
218         return path;
219     }
220     
221     /**
222      * 判断是否是根目录
223      * @param floderName
224      * @return
225      */
226     private static boolean checkIsRoot(File folder){
227         String name = getFileName(folder.getName());
228         return StringUtils.equalsIgnoreCase("/" + name, MueasConstants.FILE_UPLOAD_DIR);
229     }
230     
231     /**
232      * 获取输入文件路径或者目录路径中最后一级的名字,即可能是一个文件名,也可能是一个子目录的名字
233      * 
234      * @param file
235      * @return
236      */
237     private static String getFileName(String file){
238         String temp = new String(file);
239         temp = temp.replace("//", "/");
240         String items[] = file.split("/");
241         if(items.length > 0){
242             return items[items.length - 1];
243         }else{
244             return null;
245         }
246     }
247 }

这其中,需要细心的是动态创建的html文件,我在这里遇到了些小问题,主要是字符串拼接时格式的问题。这些,通过打印日志,还是比较容易看出来的!

 

最后,上一下测试效果图片:

点击上面鼠标所在位置的子目录后,得到下面的图片:

欢迎拍砖。