Search code examples
javauri

How can I create a java.net.URI with a query parameter that contains an ampersand in the value


This is Clojure but hopefully you can read it as a Java developer:

I am using this constructor to construct a URI.

When I have a foo query parameter with spaces and ampersand in the value, I can do this:

(new java.net.URI "https" "foobar.net" "/" "foo= hello&bye " nil )

but this creates actually two parameters since the ampersand isn't escaped:

#object[java.net.URI 0x3b809711 "https://foobar.net/?foo=%20hello&bye%20"]

If I escape the ampersand manually:

user=> (new java.net.URI "https" "foobar.net" "/" "foo= hello%26bye " nil )
#object[java.net.URI 0x5c84624f "https://foobar.net/?foo=%20hello%2526bye%20"]

you see it double-escapes my escaped ampersand. What to do here?


Solution

  • What you're trying to achieve cannot work using this constructor, since it only encodes characters which are not allowed in a URI. The % is reserved for escaping characters, so it must be escaped to %25. On the other hand, the & is a valid character used as the delimiter for query parameters and thus must not be escaped by this constructor.

    In Java I would do something like

    URI.create("https://foobar.net/?foo=" + URLEncoder.encode(" Hello&bye", "UTF-8"));
    

    or

    new URI("https://foobar.net/?foo=" + URLEncoder.encode("Hello&bye", "UTF-8"));
    

    respectively, which only escapes invalid characters in the value of the foo query parameter.