`
nicose
  • 浏览: 2347 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Fckeditor修改文件上传方式为ftp方式

阅读更多
通过对FckEditor上传附件方式的修改,目前已支持配置FTP服务器参数及HTTP服务器前缀,实现使用FTP+HTTP服务上传下载附件的功能,可用于分布式系统文本编辑中附件的统一保存。
这次修改是基于一个与Struts2集成的Fckeditor版本,原作者帖子如下:
http://www.iteye.com/topic/298154

1、Jar包中新增FckFtpConnManager和FtpHelper两个类,修改了FckAction的上传机制(浏览未作修改,可在工程中关掉浏览功能,该功能意义不大);

2、工程中在fckeditor.properties中新增配置参数:
# ftp enable
fck.ftpEnable = true        --是否采用FTP方式上传的开关,如果false,则走原始机制,将附件保存至项目下文件夹内
# ftp settings
ftp.hostName = 10.1.25.159
ftp.userName = movie
ftp.userPass = movie
ftp.port = 21
ftp.try_time = 3            --连接FTP尝试次数
# http-server settings
http.url = http://10.1.25.159:8080/attachment
        --文件服务器前缀,fck会在该前缀后拼接附件信息返回附件URL,形如:http://10.1.25.159:8080/attachment/Image/2010-02/xxxxxxxxx.jpg
3、工程中UserAction的实现类中可以配置是否允许浏览服务器上的文件。该部分未做FTP方式浏览的修改,可在以下方法中禁用浏览服务器,返回false即可。
public boolean isEnabledForFileBrowsing(HttpServletRequest arg0) {
// TODO Auto-generated method stub
return false;
} 


FtpHelper.java
package haotian.fck.action;

import haotian.fck.util.ResourceTypeHandler;
import haotian.fck.util.Utils;

import javax.servlet.http.HttpServletRequest;

public class FtpHelper {

	/**
	 * 从配置文件取ftp开关
	 * @return
	 */
	public static boolean getFtpHttpEnable() {
		String ftpHttpEnable = PropertiesLoader.getProperty("fck.ftpEnable");
		System.out.println("-----------------------------------"+ftpHttpEnable);
		return Boolean.parseBoolean(ftpHttpEnable.trim());
	}
	/**
	 * 从配置文件取http前缀
	 * @return
	 */
	public static String getHttpUrl() {
		return PropertiesLoader.getProperty("http.url").trim();
	}
	
	public static String constructResponseUrl(HttpServletRequest request,
			ResourceTypeHandler resourceType, String urlPath,
			boolean prependContextPath) {
		StringBuffer sb = new StringBuffer();
		sb.append(getHttpUrl());
		sb.append(resourceType.getPath());
		if (Utils.isNotEmpty(urlPath))
			sb.append(urlPath);
		return sb.toString();
	}
	
	/**
	 * 从配置文件取ftp连接参数
	 * @return
	 */
	public static String getHostName() {
		System.out.println("getHostName"+PropertiesLoader.getProperty("ftp.hostName").trim());
		return PropertiesLoader.getProperty("ftp.hostName").trim();
	}
	public static String getUserName() {
		System.out.println("userName"+PropertiesLoader.getProperty("ftp.userName").trim());
		return PropertiesLoader.getProperty("ftp.userName").trim();
	}
	public static String getUserPass() {
		System.out.println("userPass"+PropertiesLoader.getProperty("ftp.userPass").trim());
		return PropertiesLoader.getProperty("ftp.userPass").trim();
	}
	public static int getPort() {
		System.out.println("port"+PropertiesLoader.getProperty("ftp.port").trim());
		return Integer.parseInt(PropertiesLoader
				.getProperty("ftp.port").trim());
	}
	public static int getTryTime() {
		System.out.println("try_time"+PropertiesLoader.getProperty("ftp.try_time").trim());
		return Integer.parseInt(PropertiesLoader
				.getProperty("ftp.try_time").trim());
	}
}


FckFtpConnManager.java
package haotian.fck.action;

/**
 * Author:zhouyj2@asiainfo
 */
import haotian.fck.util.ImageInfo;

import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.StringTokenizer;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;

import sun.net.TelnetOutputStream;
import sun.net.ftp.FtpClient;
import sun.net.ftp.FtpLoginException;

public class FckFtpConnManager {
	FtpClient aFtpClient = null;

	private String hostName = null;

	private String userName = null;

	private String userPass = null;

	private int port = 21;

	private String remoteFilePath = null;

	// private String localFilePath = null;

	private int try_time = 3;

	/**
	 * 全构造方法。传入所有属性。 在以上,指定了参数从配置文件读取的情况下,只有特殊连接才使用该构造方法。
	 * 
	 * @param hostName
	 * @param port
	 * @param userName
	 * @param userPass
	 * @param remoteFilePath
	 */
	public FckFtpConnManager(String hostName, int port, String userName,
			String userPass, String remoteFilePath) {
		this.hostName = hostName;
		this.userName = userName;
		this.userPass = userPass;
		this.port = port;
		this.remoteFilePath = remoteFilePath;
	}

	/**
	 * 简单构造方法,仅传入远程路径 远程路径主要包括文件类型(Image/Flash/File)+月份(YYYY-MM)
	 * 
	 * @param remoteFilePath
	 */
	public FckFtpConnManager(String remoteFilePath) {
		this.remoteFilePath = remoteFilePath;
	}

	/**
	 * 创建文件夹
	 * 
	 * @param dir
	 * @param ftpClient
	 * @throws Exception
	 */
	private void createDir(String dir, FtpClient ftpClient) throws Exception {
		ftpClient.ascii();
		StringTokenizer s = new StringTokenizer(dir, "/"); // sign
		s.countTokens();
		String pathName = "";
		while (s.hasMoreElements()) {
			pathName = pathName + "/" + (String) s.nextElement();
			try {
				ftpClient.sendServer("MKD " + pathName + "\r\n");
			} catch (Exception e) {
				e = null;
			}
			ftpClient.readServerResponse();
		}
		ftpClient.binary();

	}

	/**
	 * 检查文件夹是否存在
	 * 
	 * @param dir
	 * @param ftpClient
	 * @return
	 */
	private Boolean isDirExist(String dir, FtpClient ftpClient) {
		try {
			ftpClient.cd(dir);
		} catch (Exception e) {

			return false;
		}
		return true;
	}

	/**
	 * 连接FTP服务器
	 * 
	 * @return
	 */
	public boolean connectServer() {
		System.out.println("get params");
		this.hostName = FtpHelper.getHostName();
		this.userName = FtpHelper.getUserName();
		this.userPass = FtpHelper.getUserPass();
		this.port = FtpHelper.getPort();
		this.try_time = FtpHelper.getTryTime();
		System.out.println("hostName"+this.hostName);
		System.out.println("username"+this.userName);
		System.out.println("userpass"+this.userPass);
		System.out.println("try_time"+this.try_time);
		if (hostName == null || hostName.equals("")) {
			System.out.println("ftp   hostname   can't   be   blank.");
			return false;
		}
		System.out.println("Connecting   to   host:   " + hostName + "...");
		try {
			aFtpClient = new FtpClient(hostName, port);
			aFtpClient.login(userName, userPass);
			aFtpClient.binary();
			// aFtpClient.cd(remoteFilePath);
		} catch (FtpLoginException e) {
			// System.out.println("无权限访问ftp主机.");
			System.out.println("not   privilidged   to   access   ftp   host.");
			return false;
		} catch (IOException e) {
			// System.out.println("连接ftp主机失败.");
			System.out.println("fail   to   connect   to   ftp   host.");
			return false;
		} catch (SecurityException e) {
			// System.out.println("无权限连接ftp主机.");
			System.out
					.println("not   privilidged   to   connect   to   ftp   host.");
			return false;
		}
		// System.out.println("ftp主机连接成功.");
		System.out.println("successful   to   connect   to   ftp   host.");
		return true;
	}

	/**
	 * 两个文件名,上传文件
	 * 
	 * @param fileName
	 * @param newFileName
	 * @return
	 * @throws Exception
	 */
	public boolean upLoadFile(String fileName, String newFileName)
			throws Exception {
		boolean connected = connectServer();
		int i = try_time;
		while (i > 0) {
			if (connected == false)
				i--;
			else
				break;
		}
		if (i <= 0)
			return false;

		RandomAccessFile sendFile = null;
		TelnetOutputStream out = null;
		DataOutputStream output = null;
		int byteData;

		try {
			sendFile = new RandomAccessFile(fileName, "r");
		} catch (IOException e) {
			// System.out.println("ftp读本地文件错误。");
			System.out.println("ftp   read   local   file   error.");
			aFtpClient.closeServer();// closeCon();
			return false;
		}
		try {
			aFtpClient.cd(remoteFilePath);
		} catch (IOException e) {
			createDir(remoteFilePath, aFtpClient);
			aFtpClient.cd(remoteFilePath);
		}
		/*
		 * catch (IOException e) { //System.out.println("远程路径错误。");
		 * System.out.println("ftp remote path error."); e.printStackTrace();
		 * aFtpClient.closeServer(); return false; }
		 */
		try {
			// System.out.println("正在发送文件:"+fileName+"...");
			System.out.println("Sending   file:   " + fileName + "...");
			sendFile.seek(0);
			System.out.println("a");
			out = aFtpClient.put(newFileName);
			File file_in = new File(fileName);
			FileInputStream is = new FileInputStream(file_in);
			byte[] bytes = new byte[1024];
			int c;
			while ((c = is.read(bytes)) != -1) {
				out.write(bytes, 0, c);
			}

			System.out.println("b");
			// output = new DataOutputStream(out);
			System.out.println("c");
			is.close();
			out.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}
	
	/**
	 * 是否大图片
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public boolean isLargeImage(File file) throws Exception {
		FileInputStream fis = null;
		try {
			int width;
			int height;
			fis = new FileInputStream(file.getPath());
			int size = fis.available() / 1024;
			if (size > FckHelper.getImageMaxSize());
			ImageInfo ii = new ImageInfo();
			ii.setInput(fis);
			height = ii.getHeight();
			width = ii.getWidth();
			if(width > FckHelper.getImageMaxWidth()&&height>FckHelper.getImageMaxHeight())
				return true;
			else
				return false;
		} catch (Exception e) {
			return false;
		} finally {
			if (fis != null)
				fis.close();
		}
	}
	
	/**
	 * 图片处理。
	 * 如果是大图片,转成小图片后上传,否则直接上传。
	 * @param upload
	 * @param newFileName
	 * @throws Exception
	 */
	public void doImageFile(File upload, String newFileName) throws Exception {
		System.out.println("upload Image~");
		if (isLargeImage(upload)) {
			createMinImage(upload, newFileName, FckHelper.getImageMaxWidth(),
					FckHelper.getImageMaxHeight());
			upload.delete();
		} else {
			uploadFile(upload, newFileName);
		}
	}
	
	/**
	 * 将大图片转成小图片
	 * @param upload
	 * @param newFileName
	 * @param toWidth
	 * @param toHeight
	 * @return
	 * @throws Exception
	 */
	public boolean createMinImage(File upload, String newFileName, int toWidth, int toHeight) throws Exception {
		System.out.println("process Big Image");
		try
	    {
	      double wRatio = 0.0D;
	      double hRatio = 0.0D;
	      double iRatio = 0.0D;

	      BufferedImage Bi = ImageIO.read(upload);

	      hRatio = toHeight / Bi.getHeight();
	      wRatio = toWidth / Bi.getWidth();
	      iRatio = (wRatio < hRatio) ? wRatio : hRatio;

	      Image Itemp = Bi.getScaledInstance((int)(toWidth * iRatio), 
	        (int)(toHeight * iRatio), 4);
	      AffineTransformOp op = new AffineTransformOp(
	        AffineTransform.getScaleInstance(iRatio, iRatio), null);
	      Itemp = op.filter(Bi, null);
	      //ImageOutputStream ios = null;
	      File temp = null;
	      ImageIO.write((BufferedImage)Itemp, "jpg", temp);
	      uploadFile(temp,newFileName);
	    } catch (Exception ex) {
	      return false;
	    }
	    return true;
	}
	/**
	 * 上传文件&新文件名,保存文件
	 * 
	 * @param uploadFile
	 * @param newFileName
	 * @return
	 * @throws Exception
	 */
	public boolean uploadFile(File uploadFile, String newFileName)
			throws Exception {
		System.out.println("do upload file");
		boolean connected = connectServer();
		System.out.println("connected:"+connected);
		int i = try_time;
		while (i > 0) {
			if (connected == false)
				i--;
			else
				break;
		}
		if (i <= 0)
			return false;

		RandomAccessFile sendFile = null;
		TelnetOutputStream out = null;
		DataOutputStream output = null;
		int byteData;

		try {
			System.out.println("create sendFile");
			sendFile = new RandomAccessFile(uploadFile.getAbsolutePath(), "r");
		} catch (IOException e) {
			// System.out.println("ftp读本地文件错误。");
			System.out.println("ftp   read   local   file   error.");
			aFtpClient.closeServer();// closeCon();
			return false;
		}
		try {
			System.out.println("enter remote path");
			aFtpClient.cd(remoteFilePath);
		} catch (IOException e) {
			createDir(remoteFilePath, aFtpClient);
			aFtpClient.cd(remoteFilePath);
		}
		/*
		 * catch (IOException e) { //System.out.println("远程路径错误。");
		 * System.out.println("ftp remote path error."); e.printStackTrace();
		 * aFtpClient.closeServer(); return false; }
		 */
		try {
			// System.out.println("正在发送文件:"+fileName+"...");
			System.out.println("Sending   file: " + uploadFile.getName()
					+ "...");
			sendFile.seek(0);
			System.out.println("a");
			out = aFtpClient.put(newFileName);
			// File file_in = new File(fileName);
			FileInputStream is = new FileInputStream(uploadFile);
			byte[] bytes = new byte[1024];
			int c;
			while ((c = is.read(bytes)) != -1) {
				out.write(bytes, 0, c);
			}

			System.out.println("b");
			// output = new DataOutputStream(out);
			System.out.println("c");
			is.close();
			out.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}

	/*public static void main(String[] args) throws Exception {
		FckFtpConnManager ftpclient = new FckFtpConnManager("10.1.25.203", 21,
				"movie", "movie", "2010-02-23");
		ftpclient.upLoadFile("D:\\testFtp\\subunsubfromsp\\test.txt",
				"tftyyy.txt");
	}*/
}


FckAction.java修改部分
在doPost方法内加入条件判断
if (!FtpHelper.getFtpHttpEnable())

在配置禁止ftp方式的情况下,按照fck原有机制,将附件上传到工程下的指定文件夹内
如果配置允许ftp方式上传附件,走以下流程
else {
			if ((Utils.isEmpty(this.commandStr))
					&& (Utils.isEmpty(this.currentFolderStr))) {
				this.commandStr = "QuickUpload";
				this.currentFolderStr = "/" + this.userAction.getCustomPath()
						+ "/";
			}
			if (this.currentFolderStr.equals("/")) {
				ur = new UploadResponse(new Object[] { Integer.valueOf(1), 0,
						0, "请按月份存放上传文件,不允许上传到根目录" });
			} else if (!(this.userAction.isEnabledForFileUpload(this.request))) {
				ur = new UploadResponse(new Object[] { Integer.valueOf(203), 0,
						0, "当前用户不允许上传文件" });
			} else if (!(CommandHandler.isValidForPost(this.commandStr))) {
				ur = new UploadResponse(new Object[] { Integer.valueOf(1), 0,
						0, "无效命令" });
			} else if ((this.typeStr != null)
					&& (!(ResourceTypeHandler.isValid(this.typeStr)))) {
				ur = new UploadResponse(new Object[] { Integer.valueOf(1), 0,
						0, "无效资源类型" });
			} else if (!(FckHelper.isValidPath(this.currentFolderStr))) {
				ur = UploadResponse.UR_INVALID_CURRENT_FOLDER;
			} else {
				ResourceTypeHandler resourceType = ResourceTypeHandler
						.getDefaultResourceType(this.typeStr);
				String remoteFilePath = resourceType.getPath()+this.currentFolderStr;
				FckFtpConnManager fcm = new FckFtpConnManager(remoteFilePath);
				//File typePath = FckHelper.getRealTypePath(resourceType.getPath());
				//System.out.println("typePath==" + typePath);
				//FckHelper.checkDirAndCreate(typePath);
				/*File currentDir = new File(typePath, this.currentFolderStr);
				System.out.println("currentDir" + currentDir.getPath());
				if (!(currentDir.exists())) {
					FckHelper.checkDirAndCreate(currentDir);

					System.out.println("UR_INVALID_CURRENT_FOLDER");
				}*/
				//this.currentFolderStr
				try {
					String rawName = FckHelper
							.sanitizeFileName(this.uploadFileName);
					String filename = FilenameUtils.getName(rawName);
					String extension = FilenameUtils.getExtension(filename);
					if (!(ExtensionsHandler.isAllowed(resourceType, extension))) {
						ur = new UploadResponse(new Object[] {Integer.valueOf(202)});
					}
					String newFilename = String.valueOf(
							System.currentTimeMillis()).concat(".").concat(
							extension);

					ur = new UploadResponse(new Object[] {
							Integer.valueOf(0),
							FtpHelper.constructResponseUrl(this.request,
									resourceType, this.currentFolderStr, true)
									.concat(newFilename) });

					//File toFile = new File(currentDir, newFilename);
					if (resourceType.equals(ResourceTypeHandler.IMAGE)) {
						if ((FckHelper.isSecureImageUploads())
								&& (!(isImageFile(this.upload)))) {
							ur = new UploadResponse(new Object[] { Integer
									.valueOf(202) });
						}
						fcm.doImageFile(this.upload, newFilename);
					} else {
						fcm.uploadFile(this.upload, newFilename);
					}
					this.userAction.doUploadFile(this.request,
							this.uploadFileName, new File(FtpHelper.getHttpUrl()+remoteFilePath+newFilename));
				} catch (Exception e) {
					System.out.println("--------sth wrong!--------");
					e.printStackTrace();
					ur = new UploadResponse(new Object[] {
							Integer.valueOf(0)});
				}
			}
分享到:
评论

相关推荐

    FCKeditor 2.6.2

    6. **插件扩展**:FCKeditor拥有一个活跃的开发者社区,提供了众多插件,如FTP上传、拼写检查、代码高亮等,进一步增强了编辑器的功能。 7. **易用性与定制**:FCKeditor界面简洁,易于上手。同时,开发者可以对其...

    通过Fckeditor把图片上传到独立图片服务器的方法

    5. 服务器安全性问题:当涉及到文件上传时,安全性是必须重点考虑的问题。文章提到,可以通过设置跨站cookies来判断是否具有上传权限,从而在一定程度上确保上传过程的安全性。 具体实现步骤如下: 1) 在图片...

    突破上传总结,用于渗透测试,很经典

    - **HTACCESS文件解析攻击**:上传.htaccess文件,利用Apache服务器的配置漏洞来更改文件的解析方式。 - **ASHX解析攻击**:利用IIS服务器对`.ashx`文件的解析漏洞,上传后缀为`.ashx`的恶意文件。 #### 文件名及...

    文件管理插件

    文件管理在IT领域中至关重要,尤其对于Web应用来说,能够高效、安全地处理文件上传、下载、修改等操作是提升用户体验的关键。以下是一些优秀的文件管理插件的详细介绍,它们可以帮助开发者快速集成文件管理功能,...

    在线编辑器 FCK 使用说明

    至于文件管理,FCKeditor内置了一个文件上传和管理的系统,用户可以通过编辑器直接上传图片、文档等文件。这个系统可以通过服务器端的接口进行扩展,以实现自定义的文件存储和管理策略。例如,你可以对接自己的FTP...

    11款基于Javascript的文件管理器

    本文将详细介绍11款基于JavaScript的文件管理器,它们为用户提供了一种便捷的方式来管理和操作服务器上的文件。 1. eXtplorer:这款文件管理器是基于PHP和ExtJS构建的,允许用户浏览、编辑、复制、移动、删除文件,...

    信息技术教学辅助平台1.04版源码

    2010.06.08 Fckeditor编辑器增加支持Flv上传并在线播放功能,签到学生显示IP,活动任务不要求作品提交时隐藏提交面板,文字评价编辑器NiceEdit部分汉化,更改活动列表样式,作品统计中增加将所有未评作品全批为P的...

    LearnSite(swfupload版) 1.2.0.1 20120708b.rar

    2012.6.27 调查选项添加编辑器kindeditor(并更新至4.11版),修改kindeditor编辑器上传和文件管理 2012.6.21 学生平台背景色添加,不好处理,又去掉背景色 2012.6.15 修正查询;增加态度分排行(点态度分显示);...

    常见的PHP开源文档管理系统介绍.pdf

    3. relayb:它是一个Ajax目录管理器,具有拖放操作、动态加载文件结构、文件上传进度提示、PDF缩略图查看等功能,同时支持多用户和多账户管理。 4. Simple Directory Listing:设计风格类似Apache HTTP服务器的目录...

    Z-Blog 2.1 Phoenix Build 130128.rar

    更强大的文章编辑器 还在苦恼1.8的FCKEditor不支持IE9、批量上传等功能吗?快来测试Z-Blog2.0吧!Z-Blog团队目前与百度uEditor合作,所以我们的Z-Blog 2.0也自带百度的uEditor。支持批量上传图片、附件,支持涂鸦,...

    Z-Blog 2.0 Doomsday Build 121221

    zblog2.0正式版 Z-Blog 2.0 Doomsday Build 121221 支持界面样式,主题更换...但是,2.0新增表情包功能,只要您通过FTP往一个文件夹上传表情,即可自动根据文件夹分组并输出表情了。 演示地址:http://www.zblogseo.com

    JAVA上百实例源码以及开源项目源代码

    Java访问权限控制源代码 1个目标文件 摘要:Java源码,文件操作,权限控制 Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流...

    java开源包1

    Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...

    java开源包11

    Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...

    java开源包2

    Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...

    java开源包3

    Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...

    java开源包6

    Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...

    java开源包5

    Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...

Global site tag (gtag.js) - Google Analytics