This is a cool little example of calling a REST web service with Apex. You enter your address and the Apex code fetches the geo coordinates from Yahoo! Maps. The service returns the data as XML.
If you want to run this demo in your own org, you will need to do the following:
Add a "Remote Site" (Setup -> Security Controls -> Remote Site Setting) with the URL: http://local.yahooapis.com
Add the XML DOM parser class to your org. It may already be present but if not you can download it from Code Share . Ron Hess' class makes life much easier than using the standard XmlReader when dealing with XML files.
You can run this example on my Developer Site.
The Visualforce page above presents the user with address fields that they submit to the controller. The controller calls the REST web service and then displays the resulting geo coordinates to the user.
< apex : page controller = " RestDemoController " tabStyle = " Contact " >
< apex : sectionHeader title = " Yahoo Maps Geocoding " subtitle = " REST Demo " />
< apex : form >
< apex : pageBlock >
< apex : pageBlockButtons >
< apex : commandButton action = " {!submit} " value = " Submit "
rerender = " resultsPanel " status = " status " />
< /apex:pageBlockButtons >
< apex : pageMessages />
This example calls Yahoo ! Map geocoding REST service with the address
you provide below . < p />
< apex : pageBlockSection >
< apex : pageBlockSectionItem >
< apex : outputLabel for = " address " > Address < /apex:outputLabel >
< apex : inputText id = " address " value = " {!address} " />
< /apex:pageBlockSectionItem >
< /apex:pageBlockSection >
< apex : pageBlockSection >
< apex : pageBlockSectionItem >
< apex : outputLabel for = " city " > City < /apex:outputLabel >
< apex : inputText id = " city " value = " {!city} " />
< /apex:pageBlockSectionItem >
< /apex:pageBlockSection >
< apex : pageBlockSection >
< apex : pageBlockSectionItem >
< apex : outputLabel for = " state " > State < /apex:outputLabel >
< apex : inputText id = " state " value = " {!state} " />
< /apex:pageBlockSectionItem >
< /apex:pageBlockSection><br/ >
< apex : actionStatus id = " status " startText = " Fetching map... " />
< apex : outputPanel id = " resultsPanel " >
< apex : outputText value = " {!geoAddress} " />
< /apex:outputPanel >
< /apex:pageBlock >
< /apex:form >
< /apex:page>
The submit method below is invoked from the Visualforce page when the user clicks the submit button. It passes the address info to the getMap method which does the GET call to the REST service. We use the XmlDom class to parse through the results and construct a GeoResult object (from the inner class) and then present the info as a String to the user on the Visualforce page.
public class RestDemoController {
public String geoAddress { get ; set ;}
public String address { get ; set ;}
public String city { get ; set ;}
public String state { get ; set ;}
// set the Yahoo Application Id
private String appId { get ; set { appId = ' DaqEkjjV34FCuqDUvZN92rQ9WWVQz58c0WHWo2hRGBuM310.qXefuBVwvJQaf1nnMCxSbg-- ' ; } }
// method called by the Visualforce page's submit button
public PageReference submit () {
List < GeoResult > results = getMap ( address , city , state );
geoAddress = results [ 0 ]. toDisplayString ();
return null ;
}
// call the REST service with the address info
public List < GeoResult > getMap ( String street , String city , String state ) {
HttpRequest req = new HttpRequest ();
Http http = new Http ();
List < GeoResult > results = new List < GeoResult > ();
// set the request method
req . setMethod ( ' GET ' );
// set the yahoo maps url with address
String url = ' http://local.yahooapis.com/MapsService/V1/geocode?appid= ' + appId
+ ' &street= ' + EncodingUtil . urlEncode ( street , ' UTF-8 ' )
+ ' &city= ' + EncodingUtil . urlEncode ( city , ' UTF-8 ' )
+ ' &state= ' + EncodingUtil . urlEncode ( state , ' UTF-8 ' );
// add the endpoint to the request
req . setEndpoint ( url );
// create the response object
HTTPResponse resp = http . send ( req );
// create the xml doc that will contain the results of the REST operation
XmlDom doc = new XmlDom ( resp . getBody ());
// process the results
XmlDom . Element [] elements = doc . getElementsByTagName ( ' Result ' );
if ( elements != null ) {
for ( XmlDom . Element element : elements )
results . add ( toGeoResult ( element ));
}
return results ;
}
// utility method to convert the xml element to the inner class
private GeoResult toGeoResult ( XmlDom . Element element ) {
GeoResult geo = new GeoResult ();
geo . latitude = element . getValue ( ' Latitude ' );
geo . longitude = element . getValue ( ' Longitude ' );
geo . address = element . getValue ( ' Address ' );
geo . city = element . getValue ( ' City ' );
geo . state = element . getValue ( ' State ' );
geo . zip = element . getValue ( ' Zip ' );
return geo ;
}
// inner class
private class GeoResult {
public String latitude ;
public String longitude ;
public String address ;
public String city ;
public String state ;
public String zip ;
public String toDisplayString () {
return address + ' , '
+ city + ' , '
+ state + ' , '
+ zip + ' [ '
+ latitude + ' , '
+ longitude + ' ] ' ;
}
}
}