In one of my Grails project I need to drop files over ftp server. Using JSch one can easily transfer files over sftp. Just follow the below steps.
1. Add the below dependency to Grails project “grails-app/conf/BuildConfig.groovy” file
dependencies {
compile 'com.jcraft:jsch:0.1.49'
}
2. Create a class for adding ftp credentials information. e.g. “FtpCredentail”
class FtpCredential {
String server
String username
String password
String remoteBaseDir
Integer port
}
3. Create a service named “FtpService” and add the following code into it
import com.jcraft.jsch.Channel
import com.jcraft.jsch.ChannelSftp
import com.jcraft.jsch.JSch
import com.jcraft.jsch.Session
class FtpService {
def grailsApplication
static transactional = true
def save(InputStream inputStream, String fileName, FtpCredential ftpCredential) {
connect(ftpCredential) { ChannelSftp sftp ->
sftp.put inputStream, fileName
}
}
def load(String fileName, FtpCredential ftpCredential) {
connect(ftpCredential, { ChannelSftp sftp ->
File outputFile = File.createTempFile(fileName,'')
outputFile?.newOutputStream() << sftp.get(fileName)
outputFile
}, false)
}
def delete(String fileName, FtpCredential ftpCredential) throws Throwable {
connect(ftpCredential) { ChannelSftp sftp ->
sftp.rm fileName
}
}
def makeDir(String directoryName, FtpCredential ftpCredential) {
connect(ftpCredential) { ChannelSftp sftp ->
sftp.mkdir directoryName
}
}
private def connect(FtpCredential ftpCredential, Closure c, boolean disconnectOnFinish = true) {
Session session = null
ChannelSftp sftp = null
try {
JSch jSch = new JSch()
session = jSch.getSession username, ftpCredential?.server, ftpCredential?.port
session.setConfig "StrictHostKeyChecking", "no"
File keyFile = new File("${grailsApplication.config.pathToKeyFile}")
if (ftpCredential?.password) {
session.password = ftpCredential?.password
} else {
jSch.addIdentity(keyFile?.absolutePath)
}
session.connect()
Channel sFtpChannel = session.openChannel "sftp"
sFtpChannel.connect()
sftp = sFtpChannel as ChannelSftp
sftp.cd ftpCredential?.remoteBaseDir
c.call sftp
} catch (Exception ex) {
ex.printStackTrace()
} finally {
if (disconnectOnFinish) {
sftp?.exit()
session?.disconnect()
}
}
}
}
Note: In the above code at line number 44.
File keyFile = new File("${grailsApplication.config.pathToKeyFile}")
The code looks for private key provided by ftp server for password-less log in. One should define the property named “pathToKeyFile” in “grails-app/conf/Config.groovy” with value equals to the path of key file.
Now you are ready to use the newly created FtpService service methods. Such as:
- save(inputStream, fileName, ftpCredential) for saving file over ftp.
- load(fileName, ftpCredential) for getting file from ftp.
- delete(fileName, ftpCredential) for deleting file over ftp.
- makeDir(directoryName, ftpCredential) for creating directory over ftp.
Example
For saving file over ftp one can use FtpService save method as shown below
File file = File.createTempFile("temp","txt")
FtpCredential ftpCredential = new FtpCredential(server: <server>, username: <username>, password: <password>, port: <server_port>, remoteBaseDir: <remote_base_directory>)
InputStream inputStream = new BufferedInputStream(new FileInputStream(file))
ftpService.save(inputStream, "fileNameToBeSavedOverFTPServer", ftpCredential)
Please share your feedback and suggestions.
Click here to read more JSch examples »
Puneet Behl
puneet.behl@intelligrape.com
https://twitter.com/puneetbhl
http://in.linkedin.com/in/puneetbhl
