jbu
jbu

Reputation: 16131

Java URL constructor ignores path segment

I am using the Java URL constructor "URL(URL context, String spec)" found here but the constructed URL is not what I expect - it is leaving out a path segment provided in the context parameter.

As an example, this code

new URL(new URL("http://asdf.com/z"), "a/b/c");

produces a URL with value

http://asdf.com/a/b/c

So it has left out of "z" path segment.

I have two questions:

  1. What is the meaning of "context" the first parameter here in the java doc? I could not find mention of it in the URL specification nor did I really find it in java doc.
  2. Is leaving out the "z" expected behavior?

Thanks!

Upvotes: 1

Views: 349

Answers (2)

Sweeper
Sweeper

Reputation: 271175

What is the meaning of "context" the first parameter here in the java doc?

It's like the "base URL" of the spec parameter. If context is https://example.com, and spec is /foo, the constructor would create https://example.com/foo. It's similar to (but not exactly the same as, as we'll see later) asking "I am currently on https://example.com, and I want to go to /foo, what would my final URL be?"

Is leaving out the "z" expected behavior?

Yes. If you follow through the rules of resolving a relative URL against an base URL in RFC 2396 with regards to this case, you will reach this step:

(6) If this step is reached, then we are resolving a relative-path reference. The relative path needs to be merged with the base URI's path. Although there are many ways to do this, we will describe a simple method using a separate string buffer.

(a) All but the last segment of the base URI's path component is copied to the buffer. In other words, any characters after the last (right-most) slash character, if any, are excluded.

(b) The reference's path component is appended to the buffer string.

The "last segment" here, refers to z, and that is not added to the buffer. Right after that, the path a/b/c "is appended to the buffer". Steps (c) onwards deals with removing . and .., which is irrelevant here.

Note that RFC 2386 doesn't say you MUST implement the algorithm in this way, but that whatever your implementation is, your output must match the output of that algorithm:

The above algorithm is intended to provide an example by which the output of implementations can be tested -- implementation of the algorithm itself is not required.

So yeah, this is expected. To keep the /z, you should add another / after the z:

new URL(new URL("http://asdf.com/z/"), "a/b/c")

This way the "last segment" becomes the empty string.

Upvotes: 2

haoyu wang
haoyu wang

Reputation: 1377

You can treat the context like the current directory in file system.
With context "http://asdf.com/z", the current directory is "http://asdf.com/", and use "a/b/c" as the spec will result a full path "http://asdf.com/a/b/c".

Upvotes: 0

Related Questions