Encoding curly braces in Jersey Client 2
Instead of manually pre-encoding the query parameter value, a better way might be do always use a template parameter and then use resolveTemplate()
with the un-safe value.
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://server")
.path("/foo")
.queryParam("bar", "{bar}")
.resolveTemplate("bar", "{\"foo\":\"bar\"}");
assertThat(target.getUri().toString())
.isEqualTo("http://server/foo?bar=%7B%22foo%22%3A%22bar%22%7D");
So, first of all it's insane that Jersey is doing templating by default. Secondly, all the solutions here are wrong...doing URLEncoder.encode(..., "UTF-8")
will not work for query params which contains spaces. Since the URLEncoder will encode the space as +
, which Jersey will interpret as a plus sign, so Jersey ends up encoding it as %2B
. See https://docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html for reference.
My proposed solution, which I'm not very happy with (as always with Java) is to replace all {
and }
with %7B
and %7D
respectively, as following:
Map<String, String> map = new HashMap<>();
map.put("paramWithCurly", " {with a space}".replaceAll("\\{", "%7B").replaceAll("\\}", "%7D"));
map.put("paramWithOutCurly", "with a space");
map.put("paramWithBracket", "[with a space]");
WebTarget target = client.target(url);
for (Map.Entry<String, String> entry : map.entrySet()) {
target = target.queryParam(entry.getKey(), entry.getValue());
}