“Expecting / to follow the hostname in URI” exception when password contains @

≯℡__Kan透↙ 提交于 2019-11-30 20:21:00

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.

As @martin-prikryl's answer states, certain characters can't appear in their raw form in the username and password fields, or else they will make the URI invalid.

The root cause here is that you're using simple string concatenation to construct the URI:

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

Java has URI and URL classes which can be used to construct URIs and URLs from individual fields. They will handle encoding each field properly. You should use one of them instead of rolling your own logic:

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

public class URITest {

    public static void main(String[] args) throws URISyntaxException {
        String user = "user";
        String passwd = "p@ss/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());
    }
}

This prints:

sftp://user:p%40ss%2Ford@example.com/some/path
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!