尝试使用此处的rest-client-builder插件
http://grails.org/plugin/rest-client-builder
在我的neo4j图表上运行cypher查询
所以我构建了一个完全符合我想要的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 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)
答案 0 :(得分: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;
}
返回值是包含data
和columns
键的地图。
旁注:要摆脱no suitable HttpMessageConverter found for request type XXX
尝试添加为BuildConfig.groovy的jar依赖:
compile 'com.fasterxml.jackson.core:jackson-databind:2.2.2'
如果你想使用参数化的密码,它会有点棘手。核心问题是RestBuilder在内部实例化了一个没有参数的JsonBuilder,但在这种情况下你需要参数,因为你的json现在是一个map而不是tree-ish结构。使用以下代码段进行服务:
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;
}
}
答案 1 :(得分:-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,但对于json
或body
,它只是一个方法调用。
答案 2 :(得分:-1)
使用json
方法代替body
方法构建消息有效内容as mentioned in the documentation。
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
会更清楚一点。