Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way to send %2b (encoded plus sign) in query arg with java.net.URI?

Tags:

java

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.

like image 823
jamshid Avatar asked Jan 25 '13 16:01

jamshid


1 Answers

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");
like image 100
jkee Avatar answered Sep 21 '22 06:09

jkee