【发布时间】:2015-06-23 06:20:49
【问题描述】:
我正在 grails 中开发一个应用程序,其中我有一些图像并且我需要在 ftp 服务器上上传。我尝试了很多东西,但仍然没有取得任何成功。 通过 grails 在 ftp 服务器上上传图像文件的最佳方法是什么?
【问题讨论】:
我正在 grails 中开发一个应用程序,其中我有一些图像并且我需要在 ftp 服务器上上传。我尝试了很多东西,但仍然没有取得任何成功。 通过 grails 在 ftp 服务器上上传图像文件的最佳方法是什么?
【问题讨论】:
到目前为止,最好的解决方案之一是Commons Virtual File System(Commons VFS)库,它在任何 Java 或 Groovy 项目中都非常有效。我在许多 Grails 应用程序中使用它来与 FTP 服务器(服务器到服务器)进行通信。
您可以将 Commons VFS 作为 BuildConfig.groovy 中的依赖项添加到您的 Grails 项目中,如下所示::
dependencies {
compile 'commons-net:commons-net:3.3'
compile 'org.apache.commons:commons-vfs2:2.0'
}
这只是一个示例,说明如何通过 Grails 服务公开 Commons VFS 的使用:
// VirtualFileSystemService.groovy
package com.example
import org.springframework.beans.factory.InitializingBean
import java.net.URLEncoder
import java.io.InputStream
import java.io.OutputStream
import java.io.ByteArrayOutputStream
import org.apache.commons.io.FileUtils
import org.apache.commons.vfs2.FileSystemManager
import org.apache.commons.vfs2.VFS
import org.apache.commons.vfs2.FileObject
import org.apache.commons.vfs2.FileSystemOptions
import org.apache.commons.vfs2.provider.ftp.FtpFileSystemConfigBuilder
import org.apache.commons.vfs2.Selectors
import org.apache.commons.vfs2.FileType
class VirtualFileSystemService implements InitializingBean {
static transactional = false
FileSystemManager vfs = VFS.getManager()
FileSystemOptions vfsFileSystemOptions = new FileSystemOptions()
void afterPropertiesSet() {
// setup FTP file system options
FtpFileSystemConfigBuilder.getInstance().setPassiveMode(vfsFileSystemOptions, true)
FtpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(vfsFileSystemOptions, true)
FtpFileSystemConfigBuilder.getInstance().setDataTimeout(vfsFileSystemOptions, 180000)
}
boolean exists(Map settings, String container, String fileName) {
FileObject fo = resolveFile(settings, container, fileName)
boolean file_exists = fo?.exists() ?: false
fo.close()
return file_exists
}
List listFiles(Map settings, String container, String fileName) {
List results = []
FileObject fo = resolveFile(settings, container, fileName)
if (!fo.exists()) return results
List files = fo.getChildren()
files.each {
results << [
type: (it.getType() == FileType.FOLDER) ? 'FOLDER' : 'FILE',
name: it.getName().getBaseName(),
size: (it.getType() == FileType.FILE) ? it.getContent().getSize() : 0
]
}
fo.close()
return results
}
void delete(Map settings, String container, String fileName) {
FileObject fo = resolveFile(settings, container, fileName)
if (fo.exists() == true) fo.delete(Selectors.SELECT_ALL)
fo.close()
}
void rename(Map settings, String container, String fileName, String newFileName) {
FileObject fo = resolveFile(settings, container, fileName)
if (fo.exists() == false) return
FileObject nfo = resolveFile(settings, container, newFileName)
fo.doRename(nfo)
fo.close()
nfo.close()
}
void createDirectory(Map settings, String container, String fileName) {
FileObject fo = resolveFile(settings, container, fileName)
if (fo.exists() == true) return
fo.createFolder()
fo.close()
}
void upload(Map settings, String container, String fileName, InputStream data) {
log.debug("Save file ${fileName} to ${container}")
FileObject pfo = resolveFile(settings, container, null)
log.debug("Parent exists?: " + pfo.exists())
FileObject fo = resolveFile(settings, container, fileName)
if (fo.exists() == false) {
try {
fo.createFile()
} catch (Exception e) {
log.error(e)
log.error(e.getMessage())
throw e
}
} else {
fo.delete()
fo.createFile()
}
long bytesCopied = org.apache.commons.io.IOUtils.copy(data, fo.content.outputStream)
log.debug("${bytesCopied} bytes uploaded.")
fo.close()
}
OutputStream download(Map settings, String container, String fileName) {
FileObject fo = resolveFile(settings, container, fileName)
if (fo.exists() == false) return null
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
org.apache.commons.io.IOUtils.copy(fo.content.inputStream, outputStream)
fo.close()
return outputStream
}
FileObject resolveFile(Map settings, String container, String fileName) {
// add any leading forward slash to container if not present
if (!container.startsWith("/")) {
container = "/" + container
}
// remove any trailing slash from container if present
if (container.endsWith("/")) {
container = container.substring(0, container.length() -1)
}
String path = "${container}/${fileName}"
if (!fileName) path = "${container}"
log.debug("resolving path for ftp://${URLEncoder.encode(settings['username'])}:${URLEncoder.encode(settings['password'])}@${settings['host']}${path}")
return vfs.resolveFile("ftp://${URLEncoder.encode(settings['username'])}:${URLEncoder.encode(settings['password'])}@${settings['host']}${path}", vfsFileSystemOptions)
}
}
【讨论】: