0

LATER EDIT: not same problem as the suggested answer. In my case, I need to build the URI, relying on the fact that the original query string is not modified.


I have a String (coming from a request query String) that is already correctly escaped, like param1=%2Ffolder1%2Ffolder2%2Ffolder%26name%202&param2=9481dxcv234.

The decoded value of param1 is /folder1/folder2/folder&name 2. Obviously, I cannot unescape that String (because of the & char in this value)...

I need to build an URI which has that original string as query value.

I tried using org.apache.http.client.utils.URIBuilder but could not get it to work: if I provide the original String to the URI(... constructor, the resulting URL is double-escaped, like param1=%252Ffolder1%252Ffolder2%252Ffolder%2526name%25202&param2=9481dxcv234.

Can I somehow do what I need ? To build an URI by passing the query string already escaped and leave it unchanged ?

Thanks.

Serban
  • 592
  • 1
  • 4
  • 24
  • Does this answer your question? [Parse a URI String into Name-Value Collection](https://stackoverflow.com/questions/13592236/parse-a-uri-string-into-name-value-collection) – Thomas Timbul Jan 28 '22 at 14:11
  • Not really... I need to build the URI, **relying** that the query string does not get changed... – Serban Jan 28 '22 at 14:19

2 Answers2

0

I think, the simplest way is unescape it first. Then you can work with url as usualy.

Cybervitexus
  • 291
  • 4
  • 19
  • I can't, as the `&` char in the value of first param would then prevent correct parsing of parameters. It should **not** be unescaped at this moment, one should unescape the query string **after** it was broken down in parameters... – Serban Jan 28 '22 at 13:30
0

You could use org.springframework.web.util.UriComponentsBuilder:

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
UriComponents components = builder.build(true); //EDIT: pass true when the URI was fully encoded already.
MultiValueMap<String, String> parameters = components.getQueryParams();

parameters.get("param1") //"%2Ffolder1%2Ffolder2%2Ffolder%26name%202"

You can then URLDecode to get what you need.

Edit:

Since you appear to be using Apache HttpClient,

List<NameValuePair> params = org.apache.http.client.utils.URLEncodedUtils.parse(new URI(url), Charset.forName("UTF-8"));

params.get("param1") //"/folder1/folder2/folder&name 2"
Thomas Timbul
  • 1,634
  • 6
  • 14
  • this **_almost_** works: when I build back the URI, it has "+" for space, instead of "%20" ... :) – Serban Jan 28 '22 at 14:45
  • A simple replacement could take care of that - `decodedValue = decodedValue.replace('+', ' ');` Also, try passing `true` to the build method, for when the URI was already fully encoded, as it seems is the case here. – Thomas Timbul Jan 31 '22 at 09:48
  • Just tried with passing 'true' and that seems to work. Have amended my answer. – Thomas Timbul Jan 31 '22 at 09:57