My Java standalone application gets a URL (which points to a file) from the user and I need to hit it and download it. The problem I am facing is that I am not able to encode the HTTP URL address properly...
Example:
URL: http://search.barnesandnoble.com/booksearch/first book.pdf
java.net.URLEncoder.encode(url.toString(), "ISO-8859-1");
returns me:
http%3A%2F%2Fsearch.barnesandnoble.com%2Fbooksearch%2Ffirst+book.pdf
But, what I want is
http://search.barnesandnoble.com/booksearch/first%20book.pdf
(space replaced by %20)
I guess URLEncoder
is not designed to encode HTTP URLs... The JavaDoc says "Utility class for HTML form encoding"... Is there any other way to do this?
Unfortunately,
org.apache.commons.httpclient.util.URIUtil
is deprecated, and thereplacement org.apache.commons.codec.net.URLCodec
does coding suitable for form posts, not in actual URL's. So I had to write my own function, which does a single component (not suitable for entire query strings that have ?'s and &'s)a solution i developed and much more stable than any other:
If you have a URL, you can pass url.toString() into this method. First decode, to avoid double encoding (for example, encoding a space results in %20 and encoding a percent sign results in %25, so double encoding will turn a space into %2520). Then, use the URI as explained above, adding in all the parts of the URL (so that you don't drop the query parameters).
Nitpicking: a string containing a whitespace character by definition is not a URI. So what you're looking for is code that implements the URI escaping defined in Section 2.1 of RFC 3986.
There is still a problem if you have got an encoded "/" (%2F) in your URL.
RFC 3986 - Section 2.2 says: "If data for a URI component would conflict with a reserved character's purpose as a delimiter, then the conflicting data must be percent-encoded before the URI is formed." (RFC 3986 - Section 2.2)
But there is an Issue with Tomcat:
So if you have got an URL with the %2F character, Tomcat returns: "400 Invalid URI: noSlash"
You can switch of the bugfix in the Tomcat startup script:
In addition to the Carlos Heuberger's reply: if a different than the default (80) is needed, the 7 param constructor should be used: