Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.net.URI resolve against only query string

Tags:

java

uri

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.

like image 466
lucasvc Avatar asked Apr 26 '12 08:04

lucasvc


2 Answers

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?

like image 63
lucasvc Avatar answered Oct 13 '22 00:10

lucasvc


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.

like image 38
Shashank Kadne Avatar answered Oct 12 '22 23:10

Shashank Kadne