2015-04-09 8 views
5

sto cercando di copiare file system locale al server"Expecting/a seguire il nome host in URI" eccezione quando password contiene @

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

Durante l'esecuzione del codice di ottenere sotto eccezione:

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 

ottenere errore alla riga

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

La password contiene carattere speciale @.

+2

Vuol la password contiene simboli? –

+2

Sì, contiene caratteri speciali @ –

risposta

6

Se la password contiene @, il parser dell'URL lo considera un utenteinfo - separatore del nome host. Quindi esegue la scansione di un nome host, fermandosi sul successivo @, che separa il nome host effettivo. Quindi controlla che il primo carattere dopo il nome host sia /, che cosa non lo è, poiché è @. La logica non ha molto senso per me, ma spiega il messaggio di errore di confusione

Expecting/a seguire il nome host in URI

Ma in ogni caso, anche se la logica era meglio, non è possibile avere un valore letterale @ nella password o nel nome utente. Devi codificarlo tramite URL su %40.

Se il nome utente/password è variabile, si dovrebbe meglio codificare genericamente con il UriParser.encode:

public static String encode(String decodedStr) 

Nota che il commento nella documentazione è sbagliato. Dice il metodo "Rimuove% nn codifiche da una stringa.", mentre in realtà li aggiunge.

4

Come indica la risposta di @ martin-prikryl, alcuni caratteri non possono apparire nella loro forma grezza nei campi nome utente e password, altrimenti renderanno l'URI non valido.

La causa principale qui è che si sta utilizzando semplice concatenazione di stringhe per costruire l'URI:

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

Java ha URI e URL classi che possono essere utilizzate per costruire URI e URL dei singoli campi. Gestiranno correttamente la codifica di ogni campo. Si dovrebbe usare uno di loro, invece di installare la propria logica:

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

Questo stampa:

sftp://user:p%40ss%[email protected]/some/path 
Problemi correlati