Any way to send %2b (encoded plus sign) in query arg with java.net.URI?
java
Solution
I run into same trouble. After some researching, I think that if you need an %2b encoding of plus symbol, it is better not to use URI class as a result. I am using code like this:
URI uri = new URI(...);
String asciiUrl = uri.toASCIIString();
String plusReplaced = asciiUrl.replace("+", "%2b");
Problem
I can't seem to find this mentioned explicitly, but it seems that you can't send an escaped plus sign ("%2b") as a query arg value if you're using java.net.URI, since the query arg is escaped. ``` // bad: http://example.com/foo?a=%252b new URI("http", null, "example.com", 80, "/foo", "a=%2b", null); ``` Tried an actual "+" character, but that gets sent as-is, so the server will interpret it as a space. ``` // bad: http://example.com/foo?a=+ new URI("http", null, "example.com", 80, "/foo", "a=+", null); ``` So I guess you just have to do the percent-encoding of the query arg keys and values yourself and use the single-argument URI constructor that doesn't escape? Maybe let URI escape the "path", since the rules are tricky (eg, the "+" character means a plus character, not a space, when in the path): ``` // good: http://example.com/foo?a=%2b new URI(new URI("http", null, "example.com", 80, "/foo", null, null).toASCIIString() + "?a=%2b"); ``` Also, the docs claim you can create a URI like this and it will be identical to the source URI: ``` URI u = ...; URI identical = new URI(u.getScheme(), u.getUserInfo(), u.getPath(), u.getQuery(), u.getFragment()); ``` but that's not true when it contains %2b ``` URI u = new URI("http://example.com:80/foo?a=%2b"); URI identical = ...; // not identical! http://example.com:80/foo?a=+ ``` Frustrating, I guess that's why everyone uses apache commons or spring classes instead? PS: http://docs.oracle.com/javase/6/docs/api/java/net/URI.html references a URI constructor that does not exist in "the following identities also hold" section. It needs to remove the "authority" parameter.