[java]
import java.io.IOException;
import org.apache.commons.net.ftp.FTP
import org.apache.commons.net.ftp.FTPClient
importorg.apache.commons.net.ftp.FTPClientConfig
import org.apache.commons.net.ftp.FTPFile
import org.apache.commons.net.ftp.FTPReply
class FtpUtils {
/**
* 用于连接ftp服务器并配置相关信息
* @return
*/
defconnect(){<<span id="7_nwp">prename="code">//获取配置信息,读取grails工程下target/classes文件夹下的FtpProperty.groovy
def config = new ConfigSlurper().parse( new File("${System.properties['user.dir']}/target/classes/FtpProperty.groovy").toURL())
FTPClient ftp = new FTPClient();
ftp.setControlEncoding("UTF-8");
int reply;
//如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
if(config.FtpProperty.port){
ftp.connect(config.FtpProperty.url,config.FtpProperty.port);
}else{
ftp.connect(config.FtpProperty.url)
}
//登录
ftp.login(config.FtpProperty.username,config.FtpProperty.password);
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)){
ftp.disconnect();
}
//指定目录
ftp.changeWorkingDirectory(config.FtpProperty.path);
return ftp;
}
/**
* 上传文件到ftp服务器上
* @param filename 文件名
* @param file 上传的文件
* @return
*/
defuploadFile(String filename, File file){
FTPClient ftp = connect();
FTPClientConfig conf=newFTPClientConfig(FTPClientConfig.SYST_NT);
conf.setServerLanguageCode("zh");
ftp.configure(conf);
ftp.setFileType(FTP.BINARY_FILE_TYPE);//使用二进制流上传文件
file.withInputStream {ostream ->
ftp.storeFile(filename, ostream)
ostream.close()
}
ftp.logout();
ftp.disconnect()
}
/**
*Description: 向FTP服务器上传文件
* @paramftpPath 上传到FTP上的路径如"/test/img/" 一定要以"/"开头并且以"/"结束
* @paramfilename 上传到FTP服务器上的文件名
* @paraminput 输入流
* @return成功返回true,否则返回false
*/
public booleanuploadFile(String ftpPath, String filename, InputStream input){
boolean success = false;
FTPClient ftp = null;
try {
ftp = connect()
FTPClientConfig conf=newFTPClientConfig(FTPClientConfig.SYST_NT);
conf.setServerLanguageCode("zh");
ftp.configure(conf);
ftp.setFileType(FTP.BINARY_FILE_TYPE);//使用二进制流上传文件
if(ftpPath != null && ftpPath != "" &&ftpPath.contains("/")){
//创建服务器远程目录结构,创建失败直接返回
if(!createDirecroty(ftpPath, ftp)){
return false;
}
//changeDirecroty(ftpPath,ftp)
}
ftp.storeFile(filename, input);
ftp.logout();
success = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
input.close();
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
return success;
}
/**
*递归进入所需要进入的目录下面
* @paramremote 路径如"/test/img/" 一定要以"/"开头并且以"/"结束
* @paramftpClient ftp客户端
*@return
*/
def changeDirecroty(Stringremote,FTPClient ftpClient){
String directory =remote.substring(0,remote.lastIndexOf("/")+1);
if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(directory)){
int start=0;
int end = 0;
if(directory.startsWith("/")){
start = 1;
}else{
start = 0;
}
end = directory.indexOf("/",start);
while(true){
String subDirectory =remote.substring(start,end)
if(!ftpClient.changeWorkingDirectory(subDirectory)){
return false;
}
start = end + 1;
end = directory.indexOf("/",start);
//检查所有目录递归完毕
if(end <= start){
break;
}
}
}
return true
}
/**
*读所传的路径,然后判断在FTP上面是否有该路径,没有则创建
* @paramremote 路径如"/test/img/" 一定要以"/"开头并且以"/"结束
* @paramftpClient ftp客户端,通过connect()方法得到
*@return
*/
def createDirecroty(Stringremote,FTPClient ftpClient){
String directory =remote.substring(0,remote.lastIndexOf("/")+1);
if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(directory)){
int start=0;
int end = 0;
if(directory.startsWith("/")){
start = 1;
}else{
start = 0;
}
end = directory.indexOf("/",start);
while(true){
String subDirectory =remote.substring(start,end)
if(!ftpClient.changeWorkingDirectory(subDirectory)){
if(ftpClient.makeDirectory(subDirectory)){
ftpClient.changeWorkingDirectory(subDirectory);
}else {
System.out.println("创建目录失败");
return false;
}
}
start = end + 1;
end = directory.indexOf("/",start);
//检查所有目录是否创建完毕
if(end <= start){
break;
}
}
}
return true
}
/**
*判断文件是否存在ftp服务器上
* @paramremote 路径如"/test/img/" 一定要以"/"开头并且以"/"结束
* @paramfileName
*@return
*/
def isExist(String filePath,String fileName){
Boolean success = false;
FTPFile[] files = null;
FTPClient client = null;
try {
client = connect()
changeDirecroty(filePath, client)
files = client.listFiles();
client.setFileType(FTP.BINARY_FILE_TYPE);
for (FTPFile f : files) {
if (f.getName().equals(fileName)) {
success = true;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (client != null) {
try {
client.logout();
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return success;
}
/**
*通过FTP上面的文件的文件名查找到这个文件,然后返回客户端
* @paramremote 路径如"/test/img/" 一定要以"/"开头并且以"/"结束
* @paramfileName
* @returnInputStream
*/
def download(String filePath,String fileName,OutputStream out) {
FTPClient client = connect()
changeDirecroty(filePath, client)
if(isExist(filePath,fileName)){
client.retrieveFile(fileName, out);
}
}
/**
* 附件删除
* @paramremote 路径如"/test/img/" 一定要以"/"开头并且以"/"结束
* @paramfileName
*@return
*/
def delete(String filePath,String fileName){
boolean success = false
FTPClient client = connect()
if(isExist(filePath, fileName)){
client.deleteFile(fileName)
success = true
}
return success
}
}
FtpUtils.groovy配置文件如下:
/ **
* 配置上传到FTP服务器的属性
* server:FTP地址、
* user:用户名
* password:密码
* path:存放在FTP上的路径
* /
FtpProperty {
url = "191.0.4.17"
port = 21
username = "aa"
password = "aa"
path = "/"
}
接下来是Controller的代码
<<spanid="3_nwp">prename="code">//上传代码
MultipartHttpServletRequest multiRequest =(MultipartHttpServletRequest) request
CommonsMultipartFile orginalFile = (CommonsMultipartFile)multiRequest.getFile("uploadfile")
InputStream input =orginalFile.getInputStream()
//saveFtpFileName为传到FTP上所需要存放的名字
if(ftpUtils.uploadFile("/测试新建文件夹/",saveFtpFileName,input)){
msg ="文件上传成功"
}else{
msg = "文件上传失败"
}</<spanid="1_nwp">pre>
Controller中上传代码是用到了spring封装的上传方法