0

I'm trying to use the MapQuest API. The API is a little funny, requiring a JSON string as an input. When this code executes, I've verified the URL is correct that is strung together, but I never get to the Log.v statement after calling HTTPGet(url.toString()). I've done some research and see that this can be caused by missing certificates, but I'm only using an http connection, not https. Of course more work is done after the httpGet, but I've only posted the relevant code. No error is ever thrown, the code just simply stops executing beyond that. I've used essentially the same code, only slightly different URLs for parsing other RESTFUL APIs. Any thoughts?

private JSONObject callMapQuestGeoCoder(Location location)
{
String APIkey=decryptKey(MapQuestEncryptedKey);
StringBuilder url=new StringBuilder();
url.append("http://open.mapquestapi.com/geocoding/v1/reverse?key="+APIkey);
url.append("&callback=renderReverse");
url.append("&json={location:{latLng:{lat:"+location.getLatitude());
url.append(",lng:"+location.getLongitude());
url.append("}}}");
HttpGet httpGet = new HttpGet(url.toString());
Log.v(TAG,""+httpGet);

EDIT: Per advice, I stuck the code in a try catch, and got this stack trace (Modified only to remove my API Key, and change the location slightly). The character that isn't valid is the { character.

 10-26 17:42:58.733: E/GeoLoc(19767): Unknown Exception foundjava.lang.IllegalArgumentException: Illegal character in query at index 117: http://open.mapquestapi.com/geocoding/v1/reverse?key=API_KEY&callback=renderReverse&json={location:{latLng:{lat:33.0207687439397,lng:-74.50922234728932}}}
PearsonArtPhoto
  • 38,970
  • 17
  • 111
  • 142
  • 1
    Two things I would check: put try catch for the whole thing and see if sth gets caught or see, if you faced the API usage limitation thing described at http://stackoverflow.com/questions/16965582/node-js-http-get-hangs-after-5-requests-to-remote-site – mico Oct 26 '13 at 21:33
  • @mico: It's not API limits, I moved the call to happen before others would have happened. I did find an exception, however, that hadn't been caught by anything. Hmmm... It seems the issue is the {. – PearsonArtPhoto Oct 26 '13 at 21:43

2 Answers2

1

According to the URI Specification (RFC 3986), the curly bracket characters are neither "reserved characters" or "unreserved characters". That means that they can only be used in a URL (or any other kind of URI) if they are "percent encoded".

Your URL contains plain (unencoded) curly bracket characters. That is invalid according to the spec ... and it is why the HttpGet constructor is throwing an exception.

Pearson's answer gives one possible way to create a legal URL. Another would be to assemble the URL using a URI object; e.g.

url = new URI("http", "open.mapquestapi.com", "/geocoding/v1/reverse",
              ("key=" + APIkey + "&callback=renderReverse" +
               "&json={location:{latLng:{lat:" + location.getLatitude() +
               ",lng:" + location.getLongitude() + "}}}"),
              "").toString();

The multi-argument URI constructors take care of any required encoding of the components ... as per the specific details in the respective javadocs. (Read them carefully!)

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

The issue is that the use of { is illegal in an HTTP get. The solution is to run the URL through a "Safe URL Encoder". The trick, per this question, is to ensure that you only run it through the part of the URL that needs it, and don't include things like &, http://, etc.

url.append("http://open.mapquestapi.com/geocoding/v1/reverse?key="+APIkey);
url.append("&callback=renderReverse");
url.append(URLEncoder.encode("&json={location:{latLng:{lat:"+location.getLatitude(),"UTF-8"));
url.append(",lng:"+location.getLongitude());
url.append(URLEncoder.encode("}}}","UTF-8"));

And the even better solution, use the non-JSON input API for Mapquest. The output still is JSON.

url.append("http://open.mapquestapi.com/geocoding/v1/reverse?key="+APIkey);
url.append("&lat="+location.getLatitude());
url.append("&lng="+location.getLongitude());
Community
  • 1
  • 1
PearsonArtPhoto
  • 38,970
  • 17
  • 111
  • 142