I am trying to copy local system file to server
package classes;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemOptions;
import org.apache.commons.vfs.Selectors;
import org.apache.commons.vfs.impl.StandardFileSystemManager;
import org.apache.commons.vfs.provider.sftp.SftpFileSystemConfigBuilder;
public class SendMyFiles {
public static void main(String[] args) {
SendMyFiles sendMyFiles = new SendMyFiles();
String fileToFTP = "zcol_30092013.xls";
sendMyFiles.startFTP(fileToFTP);
}
public boolean startFTP(String fileToFTP){
Properties prop = new Properties();
InputStream in = getClass().getResourceAsStream("/config.properties");
StandardFileSystemManager manager = new StandardFileSystemManager();
try {
prop.load(in);
String serverAddress = prop.getProperty("serverAddress").trim();
String userId = prop.getProperty("userId").trim();
String password = prop.getProperty("password").trim();
String remoteDirectory = prop.getProperty("remoteDirectory").trim();
String localDirectory = prop.getProperty("localDirectory").trim();
System.out.println("Cheking values "+serverAddress+" "+userId+" "+password+" "+remoteDirectory+" "+localDirectory);
//check if the file exists
String filepath = localDirectory;
System.out.println("filepath "+filepath);
File file = new File(filepath);
System.out.println(file+" "+file.exists());
if (!file.exists())
throw new RuntimeException("Error. Local file not found");
//Initializes the file manager
manager.init();
//Setup our SFTP configuration
FileSystemOptions opts = new FileSystemOptions();
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(
opts, "no");
SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);
//Create the SFTP URI using the host name, userid, password, remote path and file name
String sftpUri= "sftp://" + userId + ":" + password + "@" + serverAddress + "/"
+ remoteDirectory+ fileToFTP;
// Create local file object
System.out.println("sftp uri "+sftpUri);
System.out.println(file.getAbsolutePath());
FileObject localFile = manager.resolveFile(file.getAbsolutePath());
// Create remote file object
FileObject remoteFile = manager.resolveFile(sftpUri, opts);
// Copy local file to sftp server
remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);
System.out.println("File upload successful");
}
catch (Exception ex) {
ex.printStackTrace();
return false;
}
finally {
manager.close();
}
return true;
}
}
While executing the code getting below exception:
org.apache.commons.vfs.FileSystemException: Invalid absolute URI "sftp://vmsorbit:***@172.16.16.148/universe/files/zcol_30092013.xls".
at org.apache.commons.vfs.provider.AbstractOriginatingFileProvider.findFile(AbstractOriginatingFileProvider.java:62)
at org.apache.commons.vfs.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:692)
at org.apache.commons.vfs.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:620)
at classes.SendMyFiles.startFTP(SendMyFiles.java:67)
at classes.SendMyFiles.main(SendMyFiles.java:23)
Caused by: org.apache.commons.vfs.FileSystemException: Expecting / to follow the hostname in URI "sftp://vmsorbit:***@172.16.16.148/universe/files/zcol_30092013.xls".
at org.apache.commons.vfs.provider.HostFileNameParser.extractToPath(HostFileNameParser.java:155)
at org.apache.commons.vfs.provider.URLFileNameParser.parseUri(URLFileNameParser.java:49)
at org.apache.commons.vfs.provider.AbstractFileProvider.parseUri(AbstractFileProvider.java:188)
at org.apache.commons.vfs.provider.AbstractOriginatingFileProvider.findFile(AbstractOriginatingFileProvider.java:58)
... 4 more
getting error at line
FileObject localFile = manager.resolveFile(file.getAbsolutePath());
The password contains special character @
.
If your password contains @
, the URL parser considers it a userinfo/hostname separator. It then scans for a hostname, stopping on the next @
, which separates the actual hostname. Next it checks that the first character after the hostname is /
, what it is not, as it is @
. The logic does not make much sense to me, but explains the confusing error message
Expecting / to follow the hostname in URI
But in any case, even if the logic was better, you cannot have a literal @
in your password or username. You have to URL-encode it to %40
.
If your username/password is variable, you should better encode it generically using the UriParser.encode
:
public static String encode(String decodedStr)
Note that the comment in the documentation is wrong. It says the method "Removes %nn encodings from a string.", while it actually adds them.