|
通过对FckEditor上传附件方式的修改,目前已支持配置FTP服务器参数及HTTP服务器前缀,实现使用FTP+HTTP服务上传下载附件的功能,可用于分布式系统文本编辑中附件的统一保存。
这次修改是基于一个与Struts2集成的Fckeditor版本,原作者帖子如下:
http://www.iyunv.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)});
}
} |
|