1

尝试使用此处找到的 rest-client-builder 插件

http://grails.org/plugin/rest-client-builder

在我的 neo4j 图上运行密码查询

所以我构建了一个 groovy 脚本,它完全符合我的要求

@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0-RC2' )
@Grab(group='net.sf.json-lib', module='json-lib', version='2.4', classifier='jdk15' )

import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*

def query(statement, params,success, error) {
def http = new HTTPBuilder( 'http://localhost:7474' )
 http.request( POST, JSON ) {
  uri.path = '/db/data/cypher/'
  headers.'X-Stream' = 'true'
  requestContentType = JSON
  body =  [ query : statement , params : params ?: [:] ]


  response.success = { resp, json ->
    if (success) success(json)
    else {
      println "Status ${resp.statusLine} Columns ${json.columns}\nData: ${json.data}"
    }
  }

  response.failure = { resp, message ->
   def result=[status:resp.statusLine.statusCode,statusText:resp.statusLine.reasonPhrase]
   result.headers = resp.headers.collect { h -> [ (h.name) : h.value ] }
   result.message = message
   if (error) {
     error(result)
   } else {
    println "Status: ${result.status} : ${result.statusText} "
    println 'Headers: ${result.headers}'
    println 'Message: ${result.message}'
    } 
  }
 }
}

query("START v=node({id}) RETURN v",[id:170],{ println "Success: ${it.data}" },{ println "Error: ${it}" })

这将返回我想要的 json。所以我在 grails 在控制器方法中复制它时遇到了一些麻烦,所以我选择了一个插件来执行 http rest post 请求。

所以我有一个名为的服务方法CypherService

package awhinterface
import grails.converters.JSON
import grails.plugins.rest.client.RestBuilder

class CypherService {

 def query() {
     def rest = new RestBuilder()
     def resp = rest.post("http://localhost:7474"){
         contentType "application/json"
         body = [query: "START v=node(170) RETURN v"]

     }
     return resp as JSON;
  }
}

我为它写了一个非常简单的测试:

import grails.test.mixin.*
import org.junit.*
@TestFor(CypherService)
class CypherServiceTests {
   void testquery() {
     def cypherService = new CypherService()
     def myjson = cypherService.query()
     println(myjson)
   }
}

但是,我留下了这个错误:

Could not write request: no suitable HttpMessageConverter found for request type   [org.springframework.util.LinkedMultiValueMap] and content type [application/json]
org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.util.LinkedMultiValueMap] and content type [application/json]
at grails.plugins.rest.client.RestBuilder.doRequestInternal(RestBuilder.groovy:93)
at grails.plugins.rest.client.RestBuilder.post(RestBuilder.groovy:72)
at awhinterface.CypherService.query(CypherService.groovy:10)
at awhinterface.CypherServiceTests.testquery(CypherServiceTests.groovy:17)

我对http请求还是很陌生。有人有煽动吗?谢谢!

编辑

目前接受了一些建议并得到了这个

def query() {
    def rest = new RestBuilder()
    def resp = rest.post("http://localhost:7474") {
        contentType "application/json"
        uri = "/db/data/cypher/"
        body '{query: "START v=node(170) RETURN v"}'
    }
    return resp

出现此错误:

org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.util.LinkedMultiValueMap] and content type [application/json]
at grails.plugins.rest.client.RestBuilder.doRequestInternal(RestBuilder.groovy:93)
at grails.plugins.rest.client.RestBuilder.post(RestBuilder.groovy:72)
4

3 回答 3

3

@dmahapatro 的答案非常接近,但您必须省略contentType设置。服务方法应如下所示:

def query( )
{
    def rest = new RestBuilder( )
    def resp = rest.post( "http://localhost:7474/db/data/cypher" ) {
        headers.'X-Stream' = 'true'
        query = "START v=node(170) RETURN id(v)"
    }
    return resp.json;
}

返回值是一个包含一个datacolumns键的映射。

旁注:摆脱no suitable HttpMessageConverter found for request type XXX尝试将jar依赖添加到BuildConfig.groovy:

compile 'com.fasterxml.jackson.core:jackson-databind:2.2.2'

更新

如果你想使用参数化密码,那就有点棘手了。核心问题是 RestBuilder 在内部实例化了一个没有参数的 JsonBuilder,但在这种情况下你需要参数,因为你的 json 现在是一个映射而不是一个树状结构。为您的服务使用以下代码段:

import grails.plugins.rest.client.RestBuilder
import groovy.json.JsonBuilder

class CypherService {

def query() {
    def rest = new RestBuilder()
    def resp = rest.post( "http://localhost:7474/db/data/cypher" ) {
        headers.'X-Stream' = 'true'
        body(new JsonBuilder( query: "START v=node({nodeId}) RETURN id(v)",params: [ nodeId: 1]).toString())
    }
    return resp.json;
}

}

于 2013-08-05T21:14:01.677 回答
-1

尝试使用如下:

def resp = rest.post("http://localhost:7474/db/data/cypher"){
         headers.'X-Stream' = 'true'
         contentType "application/json"

         //or
         //body '{query: "START v=node(170) RETURN v"}'

         //or [as mentioned by @codelark]
         //json query: "START v=node(170) RETURN v"

         //or
         /*json {
            query = "START v=node(170) RETURN v"
         }*/
     }

//Use resp.json instead of resp as JSON
return resp.json

RequestCustomizer 将 setProperty 用于 Multipart 请求,但jsonbody只是一个方法调用。

于 2013-08-02T20:45:07.670 回答
-1

如文档中所述,使用json方法而不是body方法来构造消息有效负载。

def resp = rest.post("http://localhost:7474") {
    contentType "application/json"
    json query: "START v=node(170) RETURN v"
}

编辑:

可以使用该body方法,但您必须JSON在传递之前将地图数据转换为:

body([query: "..."] as JSON)

但是,直接使用json会更清楚一些。

于 2013-08-02T21:45:03.403 回答