22

我正在尝试解析两个 URI,但它并不像我希望的那样简单。

URI a = new URI("http://www.foo.com");
URI b = new URI("bar.html");

麻烦的a.resolve(b).toString()是现在"http://www.foo.combar.html"。我怎么能摆脱呢?

4

5 回答 5

30

听起来您可能想使用 URL 而不是 URI(它更通用,需要处理不太严格的语法。)

URI a = new URI("http://www.foo.com");
URI b = new URI("bar.html");
URI c = a.resolve(b);
c.toString()     -> "http://www.foo.combar.html"
c.getAuthority() -> "www.foo.com"
c.getPath()      -> "bar.html"

URI 的 toString() 的行为与您预期的不同,但鉴于其一般性质,它可能应该被原谅。

遗憾的是,URI 的 toURL() 方法的行为并不像我希望给你想要的那样。

URL u = c.toURL();
u.toString()     -> "http://www.foo.combar.html"
u.getAuthority() -> "www.foo.combar.html"  --- Oh dear :(

所以最好直接从一个 URL 开始以获得你想要的:

URL x = new URL("http://www.foo.com");
URL y = new URL(x, "bar.html");
y.toString() -> "http://www.foo.com/bar.html"
于 2010-03-28T23:34:32.350 回答
8

URI 还应包含最后的分隔符('/'),以解决您想要的方式:

URI a = new URI("http://www.foo.com/");
于 2011-08-16T15:19:47.060 回答
4

URI.resolve 的行为就像您在 HTML 页面上http://example.org/path/to/menu.html并单击带有href="page1.html": 的链接一样,它会切断最后一段(此处menu.html)并放置page1.html在它的位置。

( http://example.org/path/to/menu.html, page1.html) →http://example.org/path/to/page1.html

这也有效,如果您调用 resolve 的对象是一个目录,以斜杠结尾表示:

( http://example.org/path/to/, page1.html) →http://example.org/path/to/page1.html

如果它没有以斜线结尾,则结果可能不是您所期望的:

( http://example.org/path/to, page1.html) → http://example.org/path/page1.html(缺少“到”)

如果您知道要连接的 URI 的第一个参数是一个目录,但您不知道以哪种格式获取它(带有或不带有斜杠),这可能会对您有所帮助:

static URI asDirectory(URI uri) {
    String uriString = uri.toString();
    return !uriString.endsWith("/") ? URI.create(uriString.concat("/")) : uri;
}
于 2019-11-13T11:00:32.100 回答
2

好的,从 URL 定义中出现scheme://domain:port/path?query_string#fragment_id 路径前应该有 3 个斜杠(方案后有两个,路径前有一个)
可能会出现 2 种情况:

    您的 URI 中有 3 个斜杠 => 一切正常
    您的 URI 中的斜杠少于 3 个 => 您需要在 URI 的末尾添加斜杠

有我的代码片段:

String url = "http://www.foo.com";
String endSlash="";
int indexOfSlash = 0;
for(int i = 0;i<3;i++){
   int nextIndex = url.indexOf('/',indexOfSlash);
   if(!(nextIndex>0)){
      if(i>1){
         endSlash="/";
      }else{
         throw new MalformedURLException("Bad given url format, mising :// after schema");
      }
   }else{
      indexOfSlash = ++nextIndex;
   }
}
URL rightUrl = new URL(url+endSlash);
于 2011-03-22T14:52:55.617 回答
0

具有不同可能性的示例:

    URI uri = new URI( "http://www.example.org");
    System.out.println( "*** "+uri+" ***" );
    System.out.println( uri.resolve( "bar") );
    System.out.println( uri.resolve( "/bar") );
    System.out.println( uri.resolve( "bar/") );
    System.out.println( uri.resolve( "/bar/") );
    System.out.println();
    
    uri = new URI( "http://www.example.org/");
    System.out.println( "*** "+uri+" ***" );
    System.out.println( uri.resolve( "bar") );
    System.out.println( uri.resolve( "/bar") );
    System.out.println( uri.resolve( "bar/") );
    System.out.println( uri.resolve( "/bar/") );
    System.out.println();

    uri = new URI( "http://www.example.org/foo1/foo2");
    System.out.println( "*** "+uri+" ***" );
    System.out.println( uri.resolve( "bar") );
    System.out.println( uri.resolve( "/bar") );
    System.out.println( uri.resolve( "bar/") );
    System.out.println( uri.resolve( "/bar/") );
    System.out.println();
    
    uri = new URI( "http://www.example.org/foo1/foo2/");
    System.out.println( "*** "+uri+" ***" );
    System.out.println( uri.resolve( "bar") );
    System.out.println( uri.resolve( "/bar") );
    System.out.println( uri.resolve( "bar/") );
    System.out.println( uri.resolve( "/bar/") );

产生作为输出:

*** http://www.example.org ***
http://www.example.orgbar
http://www.example.org/bar
http://www.example.orgbar/
http://www.example.org/bar/

*** http://www.example.org/ ***
http://www.example.org/bar
http://www.example.org/bar
http://www.example.org/bar/
http://www.example.org/bar/

*** http://www.example.org/foo1/foo2 ***
http://www.example.org/foo1/bar
http://www.example.org/bar
http://www.example.org/foo1/bar/
http://www.example.org/bar/

*** http://www.example.org/foo1/foo2/ ***
http://www.example.org/foo1/foo2/bar
http://www.example.org/bar
http://www.example.org/foo1/foo2/bar/
http://www.example.org/bar/

综上所述:

  • 案例 1-4:如果原始 URI 没有路径,则解析使用它作为新路径的参数。如果解析参数不是以斜杠开头,那可能会产生错误的域。
  • 案例 5-8:如果原始 URI 是一个域加斜杠,resolve 使用它的参数作为新路径。双斜杠没问题。
  • 情况 10、12、14 和 16:如果原始 URI 有路径并且 resolve 参数以斜杠开头,则 resolve 用其参数替换 URI 路径。初始路径被完全丢弃。
  • 情况 9、11:如果原始 URI 的路径不是以斜线结尾,并且 resolve 参数不是以斜线开头,则 resolve 丢弃初始 uri 路径的最后一个元素并添加其参数。
  • 情况 13、15:如果原始 URI 的路径以斜杠结尾,并且 resolve 参数不是以斜杠开头,则 resolve 添加其参数。
于 2022-01-27T20:13:21.180 回答