Ankur
Ankur

Reputation: 233

How to handle ampersand in Java String and send a URL as a query parameter value?

I am trying to call a URL from Java code in the following way:

userId = "Ankur";
template = "HelloAnkur";
value= "ParamValue";
String urlString = "https://graph.facebook.com/" + userId + "/notifications?template=" +
    template + "&href=processThis.jsp?param=" + value + "&access_token=abc123";

I have the following problems in this:

  1. When I do println(urlString), I see that the urlString only has the value upto and before the first ampersand (&). That is, it looks as: https://graph.facebook.com/Ankur/notifications?template=HelloAnkur and rest of it all (which should have been &href=processThis.jsp?param=ParamValue&access_toke=abc123) gets cut off. Why is that and how can I get and keep the full value in urlString? Does & needs to be escaped in a Java String, and if yes, how to do it?
  2. Notice that I am trying to pass a (relative) URL as a parameter value in this query (the value of href as processThis.jsp?param=ParamValue. How can I pass this type of value of href without mixing it up with the query of this URL (urlString), which only has three parameters template, href and access_token? That is, how can I hide or escape ? and =? Further, what would I need to do if value was Param Value (with a space)?
  3. Notice that the template has the value HelloAnkur (with no space). But if I wanted it to have space, as in Hello Ankur, how would I do it? Should I write it as Hello%20Ankur or Hello Ankur would be fine?
  4. I need the solution in such a way that URL url = new URL(urlString) can be created, or url can be created via URI. Please describe your answer up to this point as creating a safe URL is not straight forward in Java.

Thanks!

Upvotes: 0

Views: 3017

Answers (1)

fge
fge

Reputation: 121820

(this is going to become a classic)

Use URI Templates (RFC 6570). Using this implementation (disclaimer: mine), you can avoid all encoding problems altogether:

// Immutable, can be reused as many times as you wish
final URITemplate template = new URITemplate("https://graph.facebook.com/{userId}"
    + "/notifications?template={template}"
    + "&href=processThis.jsp?param={value}"
    + "&access_token=abc123");

final Map<String, VariableValue> vars = new HashMap<String, VariableValue>();

vars.put("userId", new ScalarValue("Ankur"));
vars.put("template", new ScalarValue("HelloAnkur"));
vars.put("value", new ScalarValue("ParamValue");

// Build the expanded string
final String expanded = template.expand(vars);

// Go with the string

Note that URI templates not only allow scalar values, but also arrays (the RFC calls these "lists" -- implemented as ListValue in the above) and maps (the RFC calls these "associative arrays" -- implemented as MapValue in the above).

Upvotes: 1

Related Questions