2015-04-09 12 views
5

Próbuję skopiować lokalnego pliku systemowego z serwerem„Expecting/śledzić nazwę hosta w URI” wyjątkiem gdy hasło zawiera @

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; 
} 
} 

Podczas wykonywania kodu coraz niżej wyjątek:

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 

błąd w linii

FileObject localFile = manager.resolveFile(file.getAbsolutePath()); 

Hasło zawiera znak specjalny @.

+2

Czy Twoje hasło zawiera żadnych symboli? –

+2

Tak, zawiera znak specjalny @ –

Odpowiedz

6

Jeśli twoje hasło zawiera @, parser URL traktuje go jako userinfo - separator nazwy hosta. Następnie skanuje nazwę hosta, zatrzymując się na następnym @, który oddziela rzeczywistą nazwę hosta. Następnie sprawdza, czy pierwszy znak po nazwie hosta to /, a czym nie jest, ponieważ jest to @. Logika nie ma sensu do mnie, ale wyjaśnia mylący komunikat o błędzie

Expecting/do naśladowania tej nazwy w URI

Ale w każdym przypadku, nawet jeśli logika była lepsza, nie można dosłownie: @ w swoim haśle lub nazwie użytkownika. Musisz zakodować go na adres URL pod numerem %40.

Jeśli nazwa użytkownika/hasło jest zmienna, należy lepiej zakodować rodzajowo pomocą UriParser.encode:

public static String encode(String decodedStr) 

Należy zauważyć, że komentarz w dokumentacji jest źle. Mówi ona o metodzie "Usuwa kodowanie% nn z ciągu znaków.", podczas gdy faktycznie je dodaje.

4

Zgodnie z odpowiedzią @ martin-prikryl, niektóre znaki nie mogą pojawiać się w postaci nieprzetworzonej w polach nazwa użytkownika i hasło, w przeciwnym razie unieważnią identyfikator URI.

Przyczyną jest to, że używasz prosty ciąg konkatenacji skonstruować URI:

String sftpUri= "sftp://" + userId + ":" + password + "@" + serverAddress + "/" 
+ remoteDirectory+ fileToFTP; 

Java ma URI i URL klas, które mogą być używane do konstruowania URI i URL z poszczególnych dziedzin. Będą obsługiwać prawidłowe kodowanie każdego pola. Należy użyć jednego z nich zamiast toczenia własną logikę:

import java.net.URI; 
import java.net.URISyntaxException; 

public class URITest { 

    public static void main(String[] args) throws URISyntaxException { 
     String user = "user"; 
     String passwd = "[email protected]/ord"; 
     String host = "example.com"; 
     String path = "/some/path"; 

     String userInfo = user + ":" + passwd; 
     URI uri = new URI("sftp", userInfo, host, -1, 
       path, null, null); 
     System.out.println(uri.toString()); 
    } 
} 

Drukuje:

sftp://user:p%40ss%[email protected]/some/path 
Powiązane problemy