这个工具类是对Apache的Ftp的操作
import java.io.IOException; import org.apache.commons.net.ftp.FTP import org.apache.commons.net.ftp.FTPClient import org.apache.commons.net.ftp.FTPClientConfig import org.apache.commons.net.ftp.FTPFile import org.apache.commons.net.ftp.FTPReply class FtpUtils { /** * 用于连接ftp服务器并配置相关信息 * @return */ def connect(){
//获取配置信息,读取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 */ def uploadFile(String filename, File file){ FTPClient ftp = connect(); FTPClientConfig conf=new FTPClientConfig(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服务器上传文件 * @param ftpPath 上传到FTP上的路径如"/test/img/" 一定要以"/"开头并且以"/"结束 * @param filename 上传到FTP服务器上的文件名 * @param input 输入流 * @return 成功返回true,否则返回false */ public boolean uploadFile(String ftpPath, String filename, InputStream input) { boolean success = false; FTPClient ftp = null; try { ftp = connect() FTPClientConfig conf=new FTPClientConfig(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; } /** * 递归进入所需要进入的目录下面 * @param remote 路径如"/test/img/" 一定要以"/"开头并且以"/"结束 * @param ftpClient ftp客户端 * @return */ def changeDirecroty(String remote,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上面是否有该路径,没有则创建 * @param remote 路径如"/test/img/" 一定要以"/"开头并且以"/"结束 * @param ftpClient ftp客户端,通过connect()方法得到 * @return */ def createDirecroty(String remote,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服务器上 * @param remote 路径如"/test/img/" 一定要以"/"开头并且以"/"结束 * @param fileName * @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上面的文件的文件名查找到这个文件,然后返回客户端 * @param remote 路径如"/test/img/" 一定要以"/"开头并且以"/"结束 * @param fileName * @return InputStream */ def download(String filePath, String fileName,OutputStream out) { FTPClient client = connect() changeDirecroty(filePath, client) if(isExist(filePath,fileName)){ client.retrieveFile(fileName, out); } } /** * 附件删除 * @param remote 路径如"/test/img/" 一定要以"/"开头并且以"/"结束 * @param fileName * @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的代码//上传代码 MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request CommonsMultipartFile orginalFile = (CommonsMultipartFile) multiRequest.getFile("uploadfile") InputStream input = orginalFile.getInputStream() //saveFtpFileName为传到FTP上所需要存放的名字 if(ftpUtils.uploadFile("/测试新建文件夹/",saveFtpFileName, input)){ msg = "文件上传成功" }else{ msg = "文件上传失败" }
Controller中上传代码是用到了spring封装的上传方法