技术开发 频道

精通 Grails: 用 JSON 和 Ajax 实现异步 Grails

  远程 JSON 还是本地 JSON?

  接下来的任务是显示目的地机场附近的 10 家宾馆。这需要远程获取数据。

  应该本地存放数据,还是在处理每个请求时都远程地获取数据?对于这个问题,没有标准的答案。对于机场数据集,我觉得完全可以本地存放。这样的数据很容易得到,而且体积不大,容易存放。(美国只有 901 个机场,很多主要的机场基本上是保持不变的,这份列表不会那么快就过时)。

  如果机场数据集不稳定,并且太大不便本地存储,或者不能单独下载,那么我会更倾向于远程地请求它。您在 “Grails 服务和 Google 地图” 中用过的 geonames.org geocoding 服务提供 JSON 输出和 XML(请参阅 参考资料)。在 Web 浏览器中输入 http://ws.geonames.org/search?name_equals=den&fcode=airp&style=full&type=json。应该可以看到清单 13 所示的 JSON 结果:

  清单 13. 从 GeoNames 返回的 JSON 结果

{"totalResultsCount":1,
"geonames":[
  {
"alternateNames":[
    {
"name":"DEN","lang":"iata"},
    {
"name":"KDEN","lang":"icao"}],
  
"adminCode2":"031",
  
"countryName":"United States",
  
"adminCode1":"CO",
  
"fclName":"spot, building, farm",
  
"elevation":1655,
  
"countryCode":"US",
  
"lng":-104.6674674,
  
"adminName2":"Denver County",
  
"adminName3":"",
  
"fcodeName":"airport",
  
"adminName4":"",
  
"timezone":{
    
"dstOffset":-6,
    
"gmtOffset":-7,
    
"timeZoneId":"America/Denver"},
  
"fcl":"S",
  
"name":"Denver International Airport",
  
"fcode":"AIRP",
  
"geonameId":5419401,
  
"lat":39.8583188,
  
"population":0,
  
"adminName1":"Colorado"}]
}

  可以看到,GeoNames 服务比您在 “Grails 与遗留数据库” 中导入的 USGS 提供更多关于机场的信息。如果出现新的用户需求,例如需要知道机场的时区或海拔高度,GeoNames 还可以提供另一种令人感兴趣的结果。它还包括像 London Heathrow(LHR)和 Frankfort(FRA)这样的国际机场。您可以将 AirportMapping.iata() 转换为使用 GeoNames,这是一个课外练习。

  同时,为了显示目的地机场附近的宾馆,惟一有效的选项是利用一个远程 Web 服务。由于有数千家宾馆,而且??馆列表是不断变化的,所以必须让其他人负责管理这份列表。

  Yahoo! 提供了一个本地搜索服务,通过该服务可以搜索一个街道地址、邮政编码,甚至是一个经度/纬度点附近的企业(请参阅 参考资料)。如果您在 “RESTful Grails” 中已经注册并得到一个 developer 密匙,那么可以在这里重用它。毫不奇怪,您在那时使用的一般搜索 URI 的格式与现在要使用的本地搜索非常类似。上一次,您允许 Web 服务默认地返回 XML。但是,通过添加一个 name=value 对(output=json),就可以得到 JSON。

  在浏览器中输入以下内容(不要换行),看看 Denver International Airport 附近的宾馆的 JSON 列表:

http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=
   YahooDemo
&query=hotel&latitude=39.858409881591797&longitude=
  
-104.666999816894531&sort=distance

  清单 14 显示了 JSON 结果(删节):

  清单 14. Yahoo! 返回的 JSON 结果

{"ResultSet":
  {
"totalResultsAvailable":"803",
  
"totalResultsReturned":"10",
  
"firstResultPosition":"1",
  
"ResultSetMapUrl":"http:\/\/maps.yahoo.com\/broadband\/?tt=hotel&tp=1",
  
"Result":[
    {
"id":"42712564",
    
"Title":"Springhill Suites-Denver Arprt",
    
"Address":"18350 E 68th Ave",
    
"City":"Denver",
    
"State":"CO",
    
"Phone":"(303) 371-9400",
    
"Latitude":"39.82076",
    
"Longitude":"-104.673719",
    
"Distance":"2.63",
    [SNIP]

  现在,您有了一个可用的宾馆列表,接下来需要为其创建一个控制器方法,就像为 AirportMapping.iata() 创建该方法一样。

0
相关文章