System.out.println( new URI("http", "example.com", "/servlet", "a=x%20y", null));
The result is http://example.com/servlet?a=x%2520y , where the value of the request parameter is different from the specified one. Strange, but this happens after Javadoc:
"The percent character ("% ") is always quoted by these constructors."
We can pass the decoded string a=xy , and then get a reasonable result (?) a=x%20y .
But what if the value of the query parameter contains an "&" character? This happens, for example, if the value is a URL with request parameters. Look at this (wrong) query string: a=b&c . Ampersand must be escaped here ( a=b%26c ), otherwise it can be considered as a query parameter a=b and some garbage ( c ). If I pass this to the URI constructor, it encodes it and returns an invalid URL: ...?a=b%2526c
This problem seems to make java.util.URI useless. Did I miss something?
Summary of responses
java.net.URI knows about the existence of the request part of the URI, but does not understand the interior of the request part, which may differ for each scheme. For example, java.net.URI does not understand the internal structure of the HTTP request part. This will not be a problem if java.net.URI viewed the request as an opaque string and did not change it. But he is trying to apply some kind of general percent encoding algorithm that breaks down HTTP URLs.
Therefore, I cannot use the URI class to reliably assemble a URL from its parts, despite the fact that there are constructors for it. I would also like to mention that with Java 7 the implementation of the relativization operation is very limited, it only works if one URL is a prefix of another. These two functions (and a more compact interface for these purposes) were the reason that I was interested in java.net.URI, but none of them worked for me.
In the end, I used java.net.URL for parsing and wrote code to assemble the URLs from parts and to relativize the two URLs. I also checked the Apache class HttpClient URIBuilder and although it understands the internals of the HTTP request string, but as of 4.3, it has the same encoding problem as java.net.URI when dealing with the request part as a whole.