fckeditor上传图片路径

本文详细介绍了如何使用FCK编辑器将上传文件保存到指定路径并显示图片的方法,包括实现步骤、配置文件修改、下载文件Servlet实现及文件路径构建等关键环节。

fckeditor上传图片路径  baidu+google

fckeditor上传中文图片  baidu+google

fckeditor上传图片 绝对路径  baidu+google

http://wenku.baidu.com/view/6c75fdf0f61fb7360b4c65bd.html

http://blog.youkuaiyun.com/winnernoom/article/details/5868903

http://wenku.baidu.com/view/f0d18e8502d276a200292ee3.html

http://www.chinaz.com/web/2012/0323/241615.shtml

http://blog.chinaunix.net/uid-7450016-id-2625811.html

http://www.alixixi.com/program/a/2009011221830.shtml

 

作为web的富文本编辑器FCK大家应该不会陌生吧,最近项目中遇到一个问题,那就是每次重新启动服务器时通过FCK上传的
文件全丢失,这可能是服务器每次重启都要重新通过war部署应用程序所致。
目前有3中方案可以解决上述问题:


1、写个后台进程专门维护FCK上传的文件。
2、位FCK专门部署一个服务器。
3、重新实现FCK的上传和下载功能(是文件可以上传到任意指定的路径,非应用程序的相对路径)。

 不知网络大侠门还有没有别的解决方案,大家功能学习。
在上述方案中,第一种方案主要是在服务重启前后移动文件夹来实现的,当文件大时维护起来比较耗时,也可能在移动过程中
由于外界原因导致文件丢失。第二种方案要为FCK搭建个服务器,维护起来比较麻烦。想来想去还是用第三种方案比较合适。
 
经过阅读FCK的源码,终于找到了实现方法。现就具体的实现写下来,供网友参考,有不对的,不够合理的地方还望指正。

首先我们完成把文上传到指定的目录中。为了能满足需求我们需要实现FCK的Connector接口。在这个接口中声明了这么几个方法需
要我们去实现:
init(final ServletContext servletContext);
fileUpload(final ResourceType type, final String currentFolder, final String fileName,final InputStream inputStream)
createFolder(final ResourceType type, final String currentFolder, final String newFolder)
getFiles(ResourceType type, String currentFolder)
getFolders(final ResourceType type, final String currentFolder)
下面是Connector接口的实现类ContextConnector
  

[java]  view plain copy
  1. package com.bzlccn.oa.common.fck;  
  2. import java.io.File;  
  3. import java.io.FileFilter;  
  4. import java.io.FileOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.util.ArrayList;  
  8. import java.util.Arrays;  
  9. import java.util.HashMap;  
  10. import java.util.List;  
  11. import java.util.Map;  
  12. import javax.servlet.ServletContext;  
  13. import net.fckeditor.connector.Connector;  
  14. import net.fckeditor.connector.exception.FolderAlreadyExistsException;  
  15. import net.fckeditor.connector.exception.InvalidCurrentFolderException;  
  16. import net.fckeditor.connector.exception.InvalidNewFolderNameException;  
  17. import net.fckeditor.connector.exception.WriteException;  
  18. import net.fckeditor.handlers.ResourceType;  
  19. import net.fckeditor.tool.UtilsFile;  
  20. import org.apache.commons.io.IOUtils;  
  21. import org.apache.commons.io.filefilter.DirectoryFileFilter;  
  22. import org.apache.commons.io.filefilter.FileFileFilter;  
  23. import org.slf4j.Logger;  
  24. import org.slf4j.LoggerFactory;  
  25. public class ContextConnector implements Connector {  
  26.     private final Logger logger = LoggerFactory.getLogger(ContextConnector.class);  
  27.     protected ServletContext servletContext;  
  28.     //初始化  
  29.     public void init(final ServletContext servletContext) throws Exception {  
  30.         this.servletContext = servletContext;  
  31.         String defaultAbsolutePath = UtilsPath.getRealUserFilesAbsolutePath();  
  32.         if (defaultAbsolutePath == null) {  
  33.             logger.error("The context root cannot be resolved against the local filesystem");  
  34.             logger.info("Your servlet container/application server does not expand deployed war files");  
  35.             logger  
  36.                     .debug("Use another Connector implementation (e.g. LocalConnector) and consult http://www.fckeditor.net/forums/viewtopic.php?f=6&t=11568");  
  37.             throw new NullPointerException("The real context root cannot be resolved against the local filesystem");  
  38.         }  
  39.     }  
  40.     //把文件上传到我们指定的路径中,路径的获取在UtilsPath中实现。  
  41.     public String fileUpload(final ResourceType type, final String currentFolder, final String fileName,  
  42.             final InputStream inputStream) throws InvalidCurrentFolderException, WriteException {  
  43.         String absolutePath = UtilsPath.getRealUserFilesAbsolutePath();  
  44.         File typeDir = getOrCreateResourceTypeDir(absolutePath, type);  
  45.         File currentDir = new File(typeDir, currentFolder);  
  46.         if (!currentDir.exists() || !currentDir.isDirectory())  
  47.             throw new InvalidCurrentFolderException();  
  48.         File newFile = new File(currentDir, fileName);  
  49.         File fileToSave = UtilsFile.getUniqueFile(newFile.getAbsoluteFile());  
  50.         try {  
  51.             IOUtils.copyLarge(inputStream, new FileOutputStream(fileToSave));  
  52.         } catch (IOException e) {  
  53.             throw new WriteException();  
  54.         }  
  55.         return fileToSave.getName();  
  56.     }  
  57.     //创建文件夹  
  58.     public void createFolder(final ResourceType type, final String currentFolder, final String newFolder)  
  59.             throws InvalidCurrentFolderException, InvalidNewFolderNameException, FolderAlreadyExistsException {  
  60.         String absolutePath = UtilsPath.getRealUserFilesAbsolutePath();  
  61.         File typeDir = getOrCreateResourceTypeDir(absolutePath, type);  
  62.         File currentDir = new File(typeDir, currentFolder);  
  63.         if (!currentDir.exists() || !currentDir.isDirectory())  
  64.             throw new InvalidCurrentFolderException();  
  65.         File newDir = new File(currentDir, newFolder);  
  66.         if (newDir.exists())  
  67.             throw new FolderAlreadyExistsException();  
  68.         if (!newDir.mkdir())  
  69.             throw new InvalidNewFolderNameException();  
  70.     }  
  71.     //得到所有的文件  
  72.     public List<Map<String, Object>> getFiles(ResourceType type, String currentFolder)  
  73.             throws InvalidCurrentFolderException {  
  74.         String absolutePath = UtilsPath.getRealUserFilesAbsolutePath();  
  75.         File typeDir = getOrCreateResourceTypeDir(absolutePath, type);  
  76.         File currentDir = new File(typeDir, currentFolder);  
  77.         if (!currentDir.exists() || !currentDir.isDirectory())  
  78.             throw new InvalidCurrentFolderException();  
  79.         // collect files  
  80.         List<Map<String, Object>> files;  
  81.         Map<String, Object> fileMap;  
  82.         File[] fileList = currentDir.listFiles((FileFilter) FileFileFilter.FILE);  
  83.         files = new ArrayList<Map<String, Object>>(fileList.length);  
  84.         for (File file : fileList) {  
  85.             fileMap = new HashMap<String, Object>(2);  
  86.             fileMap.put(Connector.KEY_NAME, file.getName());  
  87.             fileMap.put(Connector.KEY_SIZE, file.length());  
  88.             files.add(fileMap);  
  89.         }  
  90.         return files;  
  91.     }  
  92.     //得到所有文件夹  
  93.     public List<String> getFolders(final ResourceType type, final String currentFolder)  
  94.             throws InvalidCurrentFolderException {  
  95.         String absolutePath = UtilsPath.getRealUserFilesAbsolutePath();  
  96.         File typeDir = getOrCreateResourceTypeDir(absolutePath, type);  
  97.         File currentDir = new File(typeDir, currentFolder);  
  98.         if (!currentDir.exists() || !currentDir.isDirectory())  
  99.             throw new InvalidCurrentFolderException();  
  100.         String[] fileList = currentDir.list(DirectoryFileFilter.DIRECTORY);  
  101.         return Arrays.asList(fileList);  
  102.     }  
  103.     //根据上传文件的类型创建目录。  
  104.     protected static File getOrCreateResourceTypeDir(final String baseDir, final ResourceType type) {  
  105.         File dir = new File(baseDir, type.getPath());  
  106.         if (!dir.exists())  
  107.             dir.mkdirs();  
  108.         return dir;  
  109.     }  
  110. }  

 

上述ContextConnector类中用到的UtilsPath工具类的代码如下:

[java]  view plain copy
  1. package com.bzlccn.oa.common.fck;  
  2. import org.slf4j.Logger;  
  3. import org.slf4j.LoggerFactory;  
  4. import com.bzlccn.oa.common.util.Constants;  
  5. import com.bzlccn.oa.common.util.OSUtil;  
  6. import com.bzlccn.oa.common.util.exception.SystemConfigrationException;  
  7. public class UtilsPath {  
  8.     private static final Logger logger = LoggerFactory.getLogger(UtilsPath.class);  
  9.     public static String getRealUserFilesAbsolutePath() {  
  10.         String path = "";  
  11.         try {     
  12.             //需要判断所用操作系统,根据不同的系统设置路径。  
  13.             if (OSUtil.isUnixLikeSystem() == true) {  
  14.                 path = Constants.getPropertyOf(Constants.FCK_LINUX_PATH);  
  15.             } else {  
  16.                 path = Constants.getPropertyOf(Constants.FCK_WINDOWS_PATH);  
  17.             }  
  18.         } catch (SystemConfigrationException e) {  
  19.             if (OSUtil.isUnixLikeSystem() == true) {  
  20.                 path = "//usr/local/OA//fck";  
  21.             } else {  
  22.                 path = "c://oa//fck";  
  23.             }  
  24.             logger.info("配置文件出错,使用默认路径("+path+")保存fck上传文件");  
  25.         }  
  26.         return path;  
  27.     }  
  28. }  

 

为了使上传的文件跨平台(目前只支持liunx和windwos)还需要当前用的系统。工具类如下:

[c-sharp]  view plain copy
  1. package com.bzlccn.oa.common.util;  
  2. public class OSUtil {  
  3.     private static final String WINDOWS = "WINDOWS";  
  4.     /** 
  5.      *  判断当前操作系统的类型 
  6.      * 
  7.      * @return false means window system ,true means unix like system 
  8.      */  
  9.      public static boolean isUnixLikeSystem(){  
  10.          String name = System.getProperty(Constants.OS_NAME_KEY) ;  
  11.          if(name != null){  
  12.              if(name.toUpperCase().indexOf(WINDOWS) == -1){ //it means it's unix like system  
  13.                  return true;  
  14.              }  
  15.          }  
  16.          return false;  
  17.      }  
  18. }  

 

为了实现上传路径可灵活配置还需要写个读取配置文件的工具类:

 

[java]  view plain copy
  1. package com.bzlccn.oa.common.util;  
  2. import org.apache.commons.configuration.Configuration;  
  3. import org.apache.commons.configuration.ConfigurationException;  
  4. import org.apache.commons.configuration.PropertiesConfiguration;  
  5. import com.bzlccn.oa.common.util.exception.SystemConfigrationException;  
  6. public class Constants {  
  7.      
  8.     //fck文件上传  
  9.     public static final String FCK_WINDOWS_PATH="fck.windows.path";  
  10.     public static final String FCK_LINUX_PATH="fck.linux.path";  
  11.     static{  
  12.         try {  
  13.             config = new PropertiesConfiguration("fckeditor.properties");  
  14.         } catch (ConfigurationException e) {  
  15.             e.printStackTrace();  
  16.         }  
  17.     }  
  18.       
  19.     public static String getPropertyOf(String key) throws SystemConfigrationException{  
  20.         if(config == null) {  
  21.             throw new SystemConfigrationException("can not configure system");  
  22.         }  
  23.         return config.getString(key);  
  24.     }  
  25.       
  26.     public static void main(String args[]) throws ConfigurationException, SystemConfigrationException{  
  27.         System.out.println(getPropertyOf("port"));  
  28.     }  
  29. }  

 

到此为把文件上传到指定路径的功能已经基本实现,只要让FCK调用我们的ContextConnector类就可以了,怎么去让FCK调用我们自己
实现的这个ContextConnector类呢,只要配置一下配置文件就可以了。只要在FCK的配置文件中添加如下配置文件即可:
connector.impl=com.bzlccn.oa.common.fck.ContextConnector

下面就是把我们上传的文件怎么显示的问题。实现是这样的,首先我们要自己写个下载文件的servlet,具体代码如下:

[java]  view plain copy
  1. package com.bzlccn.oa.common.fck;  
  2. import java.io.FileInputStream;  
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import javax.servlet.ServletException;  
  6. import javax.servlet.ServletOutputStream;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. import org.apache.taglibs.standard.extra.spath.Path;  
  11. public class FCKDownloadServlet extends HttpServlet {  
  12.     private static final long serialVersionUID = -5742008970929377161L;  
  13.     @Override  
  14.     protected void doGet(final HttpServletRequest request,  
  15.             final HttpServletResponse response) throws ServletException,  
  16.             IOException {  
  17.                   doPost(request,response);  
  18.     }  
  19.     @Override  
  20.     protected void doPost(final HttpServletRequest request,  
  21.             final HttpServletResponse response) throws ServletException,  
  22.             IOException {  
  23.         String path=request.getParameter("path");  
  24.         request.setCharacterEncoding("UTF-8");  
  25.         response.setCharacterEncoding("UTF-8");  
  26.         setResponseContentType(response,path);  
  27.         response.setHeader("Cache-Control""no-cache");  
  28.         if (path!=null) {  
  29.             path=UtilsPath.getRealUserFilesAbsolutePath()+path;  
  30.         }else{  
  31.             path=this.getServletContext().getRealPath("/images/sign/no.JPG");  
  32.         }  
  33.         InputStream is = new FileInputStream(path);  
  34.         ServletOutputStream  servletOutputStream=response.getOutputStream();  
  35.         // 循环取出流中的数据  
  36.         byte[] b = new byte[100];  
  37.         int len;  
  38.         try {  
  39.             while ((len = is.read(b)) > 0) {  
  40.                 servletOutputStream.write(b, 0, len);  
  41.             }  
  42.         } catch (IOException e) {  
  43.             e.printStackTrace();  
  44.         }finally{  
  45.             if (servletOutputStream!=null) {  
  46.                 servletOutputStream.flush();  
  47.                 servletOutputStream.close();  
  48.             }  
  49.             if(is != null) is.close();  
  50.         }  
  51.     }  
  52.     /** 
  53.      * 根据文件扩展名设置contenttype 
  54.      * @param eresponse 
  55.      * @param path 
  56.      */  
  57.     private void setResponseContentType(HttpServletResponse response,String path){  
  58.         String contentType="image/jpg;charset=UTF-8";  
  59.         if (path!=null) {  
  60.             String exName=path.substring(path.lastIndexOf(".")+1);  
  61.             if ("bmp|gif|jpeg|jpg|png".indexOf(exName.toLowerCase())>=0) {  
  62.                 contentType="image/"+exName+";charset=UTF-8";  
  63.             }  
  64.             if ("swf|fla".indexOf(exName.toLowerCase())>=0) {  
  65.                 contentType="application/x-shockwave-flash;charset=UTF-8";  
  66.             }  
  67.         }  
  68.         response.setContentType(contentType);  
  69.     }  
  70.       
  71. }  

 

为了让FCK显示图片的时候调用我们的FCKDownloadServlet还需去重载ServerRootPathBuilder类中的getUserFilesPath方法,实现如下

[java]  view plain copy
  1. package com.bzlccn.oa.common.fck;  
  2. import javax.servlet.http.HttpServletRequest;  
  3. import net.fckeditor.requestcycle.impl.ServerRootPathBuilder;  
  4. public class ContextPathBuilder extends ServerRootPathBuilder {  
  5.     @Override  
  6.     public String getUserFilesPath(final HttpServletRequest request) {  
  7.         return request.getContextPath().concat("/fck/download.servlet?path=");//"/fck/download.servlet?"要和web.xml中配置的FCKDownloadServlet路径一致。  
  8.     }  
  9. }  

 

上述类中getUserFilesPath方法主要就是获取显示文件的路径。怎么让FCK调用我们的getUserFilesPath方法的,通要的还是要
向FCK配置文件中写入:
connector.userPathBuilderImpl = com.bzlccn.oa.common.fck.ContextPathBuilder
哈哈,这样就可以了,等等,还没有完呢,还得需要配置FCKDownloadServlet呢,在web.xml中需要输入:
 <servlet>
  <servlet-name>ConnectorServlet</servlet-name>
  <servlet-class>net.fckeditor.connector.ConnectorServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
 <servlet>
  <servlet-name>FCKDownloadServlet</servlet-name>
  <servlet-class>com.bzlccn.oa.common.fck.FCKDownloadServlet</servlet-class>
 </servlet>


 <servlet-mapping>
  <servlet-name>ConnectorServlet</servlet-name>
  <!-- Do not wrap this line otherwise Glassfish will fail to load this file -->
  <url-pattern>/fckeditor/editor/filemanager/connectors/*</url-pattern>
 </servlet-mapping>
        
    <servlet-mapping>
  <servlet-name>FCKDownloadServlet</servlet-name>
  <url-pattern>/fck/download.servlet</url-pattern>
 </servlet-mapping>

下面再把FCK的整体配置文件贴出来:
connector.userActionImpl=net.fckeditor.requestcycle.impl.EnabledUserAction
connector.impl=com.bzlccn.oa.common.fck.ContextConnector
connector.userPathBuilderImpl = com.bzlccn.oa.common.fck.ContextPathBuilder
fck.windows.path=c:/oa/fck
fck.linux.path=/home/oa/fck
还需要说明一点就是我们用的FCK的版本是2.6.5
写的有点匆忙,难免有不妥之处望指正,多拍砖。

实现效果如图:

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值