【问题标题】:JSON in Groovy / GrailsGroovy / Grails 中的 JSON
【发布时间】:2009-08-24 17:45:00
【问题描述】:

我正在尝试通过他们的 JSON 导出访问网站。

网址是:http://neotest.dabbledb.com/publish/neotest/f820728c-4451-41f6-b346-8cba54e52c6f/projects.jsonp

我正在使用 HTTPBuilder 尝试在 Groovy 中完成此任务,但遇到了麻烦。我使用来自http://groovy.codehaus.org/HTTP+Builder 的示例代码来提出这个:

// perform a GET request, expecting JSON response data
http.request( GET, JSON ) {
    url.path = 'publish/neotest/f820728c-4451-41f6-b346-8cba54e52c6f/projects.jsonp'

    // response handler for a success response code:
    response.success = { resp, json ->
        println resp.statusLine

        // parse the JSON response object:
        json.responseData.results.each {
            println "  ${it.titleNoFormatting} : ${it.visibleUrl}"
        }
    }
}

但是,当我对该方法运行单元测试时,我只是得到了 No such property: GET for class: ProjectController groovy.lang.MissingPropertyException: No such property: GET for class: ProjectController,我无法理解。

【问题讨论】:

    标签: json grails groovy


    【解决方案1】:

    您的示例代码存在一些问题。首先,要以这种方式访问​​ GET 和 JSON,您需要静态导入它们:

    import static groovyx.net.http.Method.GET
    import static groovyx.net.http.ContentType.JSON
    

    这将使代码编译,但不能成功运行。您的 url.path 值需要一个前导“/”(如 HTTPBuilder page 所示)。更重要的是,从the URL you're referencing 返回的 JSON 与执行 Google 搜索的示例代码返回的结构完全不同。如果您将your URL 加载到非常方便的JSON Formatter service at CuriousConcept 中,您将看到结构。下面是显示一些 JSON 数据的代码:

    println json.name
    println json.id
    json.fields.each {
      println it
    }
    

    顺便说一句,version 0.5.0 of HTTPBuilder 中有一个与此代码相关的重大更改。正如 RC-1 发布公告所述,

    HTTPBuilder 类的 URL 属性已重命名为 uri

    因此,如果您在某个时候移至 0.5.0,则需要使用 uri.path 而不是 url.path

    【讨论】:

      【解决方案2】:

      如果你只是想获取数据,你可以在 Grails 中这样做:

      import grails.converters.*;
      
      def url = new URL("http://neotest.dabbledb.com/publish/neotest/f820728c-4451-41f6-b346-8cba54e52c6f/projects.jsonp")
      def response = JSON.parse(url.newReader()) // response is an instance of JSONObject (see Grails API docs)
      
      println response.toString(3) // Pretty-printed output
      response.each { key, value ->
          println "$key = $value"
      }
      

      (只是作为一个简单的选择)

      【讨论】:

      • 这里小心!此示例将泄漏阅读器(进而泄漏 java.net.HttpURLConnection 和套接字!),并且它不会使用远程服务器指定的字符编码(而是使用您平台的默认编码)。换句话说: URL.newReader 在一般情况下是坏的
      【解决方案3】:

      我对 HTTPBuilder 不熟悉,但是看看文档,你可能可以通过替换来解决

      http.request( GET, JSON ) {
      

      http.request( Method.GET, ContentType.JSON ) {
      

      您可能还必须:

      import groovyx.net.http.Method
      import groovyx.net.http.ContentType
      

      我基于HttpBuilder.request() 的文档,它需要Method 和一个对象(可以是ContentType)。

      【讨论】:

      • 我绝不会拘泥于 HTTPBuilder,这正是 Google 的一些顶级条目对来自 Grails 的 JSON 调用的建议。如果您推荐其他解决方案,我完全赞成,因为我在这里没有取得太大进展。
      • 很多人推荐 Apache 的 HttpClient,HTTP Builder 似乎是基于它的,所以它可能是最好的选择。我只是想帮助解决您的 Groovy 脚本中出现的编译错误。如果 HTTP Builder 不起作用,您可以在使用 HttpClient 甚至 java.net.* 的 Groovy 中编写一些直接的 Java,尽管代码会多一些。
      【解决方案4】:

      我们可以使用 JsonSlurper 类解析 JSON 文本。我们只需要将文本提供给 parseText() 方法,我们就可以将值映射到 Maps 和 Lists。然后获取内容非常容易

      def slurper = new JsonSlurper()
       def result = slurper.parseText('{"person":{"name":"Guillaume","age":33,"pets":["dog","cat"]}}')
      
       assert result.person.name == "Guillaume"
       assert result.person.age == 33
      
       assert result.person.pets.size() == 2
       assert result.person.pets[0] == "dog"
       assert result.person.pets[1] == "cat"
      
       or
      
       result.person.pets.each{
              println it
       }
      

      【讨论】:

        【解决方案5】:

        虽然没有回答最初的问题,但我注意到您询问了其他可能的库。撇开我没有用过的 Groovy 不谈,在我看来,最好和最简单的用于构建 Web 服务客户端的 Java 库是 Jersey,毫无疑问。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-13
          • 2011-03-07
          • 2015-09-03
          • 1970-01-01
          • 2014-12-04
          • 1970-01-01
          相关资源
          最近更新 更多