1

I would like to encode only the query keys and parameters of a url (don't want to encode the /, ? or &). What's the best way to do this in Java?

For example, I want to convert

http://www.hello.com/bar/foo?a=,b &c =d

to

http://www.hello.com/bar/foo?a=%2Cb%20&c%20=d

Popcorn
  • 5,188
  • 12
  • 54
  • 87
  • 2
    Extract and parse the query components; rebuild the URL. Practically, I would use a regular expression replace with the appropriate encoding applied on the replacement. The pattern for the supplied URL, with captures, might look like: `\b(\w[^=]*)=([^&]*)` – user2864740 Mar 19 '14 at 21:30
  • `URL url = new URL(...); String query = URLEncoder.encode(url.getQuery(), ...); String encoded = url.getPath() + "?" + query;` or something like that; I don't recall the specifics of the various `URL.getXXX()`'s off the top of my head. – Jason C Mar 19 '14 at 21:39
  • @user2864740 You can just use `URL` to parse and extract the components; and `URLEncoder` is part of the JDK as well and encodes arbitrary strings. – Jason C Mar 19 '14 at 21:40
  • @JasonC Perhaps, but I'm not confident enough on how the first URL will be parsed as it requires some "leniency" - particularly on the the "c " parameter name in this case; it may also require additional relaxed parsing if different unescaped/reserved characters were also included. – user2864740 Mar 19 '14 at 21:42

2 Answers2

0

Build the url something like this:

String url = "http://www.hello.com/bar/foo?";
url += "a=" + URLEncoder.encode(value_of_a);
url += "&c=" + URLEncoder.encode(value_of_c);
developerwjk
  • 8,619
  • 2
  • 17
  • 33
0

I'm going to leave the actual component encoding as a user-supplied function because it is an existing well-discussed problem without a trivial JCL solution .. In any case, the following is how I would approach this particular problem without the use of third-party libraries.

While regular expressions sometimes result in two problems, I am hesitant to suggest a more strict approach such as URI because I don't know how it will - or even if it will - work with such funky invalid URLs. As such, here is a solution using a regular expression with a dynamic replacement value.

// The following pattern is pretty liberal on what it matches;
// It ought to work as long as there is no unencoded ?, =, or & in the URL
// but, being liberal, it will also match absolute garbage input.
Pattern p = Pattern.compile("\\b(\\w[^=?]*)=([^&]*)");
Matcher m = p.matcher("http://www.hello.com/bar/foo?a=,b &c =d");
StringBuffer sb = new StringBuffer();
while (m.find()) {
    String key = m.group(1);
    String value = m.group(2);
    m.appendReplacement(sb,
        encodeURIComponent(key) + "=" encodeURIComponent(value));
}
m.appendTail(sb);

See the ideone example example with a fill-in encodeURIComponent.

Community
  • 1
  • 1
user2864740
  • 60,010
  • 15
  • 145
  • 220