Reputation: 383
I'm trying to resolve two URIs, but it's not as straightforward as I'd like it to be.
URI a = new URI("http://www.foo.com");
URI b = new URI("bar.html");
The trouble is that a.resolve(b).toString()
is now "http://www.foo.combar.html"
. How can I get away with that?
Upvotes: 29
Views: 29860
Reputation: 3529
Example with the different posibilities:
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/") );
produces as output:
*** 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/
In conclusion:
Upvotes: 2
Reputation: 10112
URI.resolve behaves like if you are on a HTML page like http://example.org/path/to/menu.html
and click a link with href="page1.html"
: It cuts off the last segment (here menu.html
) and puts page1.html
in its place.
(http://example.org/path/to/menu.html
, page1.html
) → http://example.org/path/to/page1.html
This works also, if the object you call resolve on is a directory, denoted by ending in a slash:
(http://example.org/path/to/
, page1.html
) → http://example.org/path/to/page1.html
If it does not end in a slash, the outcome is not what you might expect:
(http://example.org/path/to
, page1.html
) → http://example.org/path/page1.html
(missing "to")
If you know that the first argument of the URIs to concatenate is a directory, but you don’t know in which format you get it (with or without trailing slash), this might help you:
static URI asDirectory(URI uri) {
String uriString = uri.toString();
return !uriString.endsWith("/") ? URI.create(uriString.concat("/")) : uri;
}
Upvotes: 10
Reputation: 139
URI should contain the final separator('/') as well to resolve the way you want:
URI a = new URI("http://www.foo.com/");
Upvotes: 13
Reputation: 1124
Ok, appears from URL deffinition scheme://domain:port/path?query_string#fragment_id
there should be 3 slashes before path (two after scheme and one directly before path)
2 situation can occure:
there is my snappet of code:
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);
Upvotes: 2
Reputation: 10772
Sounds like you probably want to use URL rather than URI (which is more general and needs to deal with a less strict syntax.)
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's toString() doesn't behave as you might expect, but given its general nature it may be that it should be forgiven.
Sadly URI's toURL() method doesn't behave quite as I would have hoped to give you what you want.
URL u = c.toURL();
u.toString() -> "http://www.foo.combar.html"
u.getAuthority() -> "www.foo.combar.html" --- Oh dear :(
So best just to start straight out with a URL to get what you want:
URL x = new URL("http://www.foo.com");
URL y = new URL(x, "bar.html");
y.toString() -> "http://www.foo.com/bar.html"
Upvotes: 35