I'm trying to build URI's using the JDK java.net.URI.
I want to append to an absolute URI object, a query (in String). In example:
URI base = new URI("http://example.com/something/more/long");
String queryString = "query=http://local:282/rand&action=aaaa";
URI query = new URI(null, null, null, queryString, null);
URI result = base.resolve(query);
Theory (or what I think) is that resolve should return:
http://example.com/something/more/long?query=http://local:282/rand&action=aaaa
But what I got is:
http://example.com/something/more/?query=http://local:282/rand&action=aaaa
Why #resolve() "eats" the last path? If the new URI (query
) is built as:
URI query = new URI(null, null, base.getPath(), queryString, null);
It works well.
I'd like to respond myself. Javadoc really explains correctly. As URI#resolve() says, in section 3.b.:
Otherwise the given URI's path is relative, and so the new URI's path is computed by resolving the path of the given URI against the path of this URI. This is done by concatenating all but the last segment of this URI's path, if any, with the given URI's path and then normalizing the result as if by invoking the normalize method.
So.... I didn't read correctly. Should I delete this response? Or let it responsed by myself?
First Case:
base = http://example.com/something/more/long
and query
evaluates to be
query = ?query=http://local:282/rand&action=aaaa.
According to the documentation of method public URI resolve(URI uri)
, it resolves the query URI against the base URI. While resolving if the method finds a path in the query URI, it assigns the same path to the new resolved URI. In this case there is no path associated with the query
. If you see the below snippet of the resolve()
function, it will get more clear.
//snippet
String cp = (child.path == null) ? "" : child.path;
if ((cp.length() > 0) && (cp.charAt(0) == '/')) {
// 5.2 (5): Child path is absolute
ru.path = child.path;
} else {
// 5.2 (6): Resolve relative path
ru.path = resolvePath(base.path, cp, base.isAbsolute());
}
where cp is the child(in your case query path). As its null here, the flow goes into the else loop where the resolved query is a assigned a path from the base URI.
Your new URI has this path /something/more/
, as it strips everything after the last "/" character.
Second Case:
base = http://example.com/something/more/long
and query
evaluates to be
query = /something/more/long?query=http://local:282/rand&action=aaaa
Here it goes to the if loop which assigns the query path to the new URI's path. Path of your query URI is /something/more/long
here i.e it includes the "long" value as well. May be this is how they resolve the URI's. Look through the documentation you will have a more clear idea of it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With