我是Groovy新手并尝试从groovy脚本连接到GitHub API但是当HTTPBuilder尝试解析JSON响应时,我收到一个奇怪的错误。
我的简单脚本如下
@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.2' )
import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
def apiToken = '[api_token]'
def http = new HTTPBuilder( 'https://api.github.com/' )
// perform a GET request, expecting JSON response data
http.request( GET, JSON ) {
uri.path = '/orgs/octokit/repos'
headers.'Accept' = 'application/json'
headers.'Authorization' = 'Basic ' + (apiToken + ':').bytes.encodeBase64().toString()
headers.'User-Agent' = '[username]'
// response handler for a success response code:
response.success = { resp, json ->
println resp.statusLine
}
// handler for any failure status code:
response.failure = { resp ->
println "Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}"
}
}
但是当解析JSON时,我得到以下错误
Sep 06, 2014 10:21:54 PM groovyx.net.http.HTTPBuilder$1 handleResponse
WARNING: Error parsing 'application/json; charset=utf-8' response
groovy.json.JsonException: expecting '}' or ',' but got current char '"' with an int value of 34
The current character read is '"' with an int value of 34
expecting '}' or ',' but got current char '"' with an int value of 34
line number 1
index number 256
[{"id":417862,"name":"octokit.rb","full_name":"octokit/octokit.rb","owner":{"login":"octokit","id":3430433,"avatar_url":"https://avatars.githubusercontent.com/u/3430433?v=2","gravatar_id":"43f38795089d56a2a7092b7d0c71fa76","url":"h
................................................................................................................................................................................................................................................................^
at groovy.json.internal.JsonParserCharArray.complain(JsonParserCharArray.java:162)
at groovy.json.internal.JsonParserCharArray.decodeJsonObject(JsonParserCharArray.java:152)
at groovy.json.internal.JsonParserCharArray.decodeValueInternal(JsonParserCharArray.java:196)
at groovy.json.internal.JsonParserCharArray.decodeJsonObject(JsonParserCharArray.java:140)
at groovy.json.internal.JsonParserCharArray.decodeValueInternal(JsonParserCharArray.java:196)
at groovy.json.internal.JsonParserCharArray.decodeJsonArray(JsonParserCharArray.java:346)
at groovy.json.internal.JsonParserCharArray.decodeValueInternal(JsonParserCharArray.java:192)
at groovy.json.internal.JsonParserCharArray.decodeValue(JsonParserCharArray.java:166)
at groovy.json.internal.JsonParserCharArray.decodeFromChars(JsonParserCharArray.java:45)
at groovy.json.internal.JsonParserCharArray.parse(JsonParserCharArray.java:409)
at groovy.json.internal.BaseJsonParser.parse(BaseJsonParser.java:121)
at groovy.json.JsonSlurper.parse(JsonSlurper.java:224)
at groovyx.net.http.ParserRegistry.parseJSON(ParserRegistry.java:280)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1207)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1074)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
at groovy.lang.Closure.call(Closure.java:423)
at groovy.lang.Closure.call(Closure.java:439)
at groovyx.net.http.HTTPBuilder.parseResponse(HTTPBuilder.java:560)
at groovyx.net.http.HTTPBuilder$1.handleResponse(HTTPBuilder.java:489)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:1070)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:1044)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:515)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:434)
at groovyx.net.http.HTTPBuilder.request(HTTPBuilder.java:383)
at groovyx.net.http.HTTPBuilder$request.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)
at sprint-snapshot.run(sprint-snapshot.groovy:11)
at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:258)
at groovy.lang.GroovyShell.run(GroovyShell.java:502)
at groovy.lang.GroovyShell.run(GroovyShell.java:491)
at groovy.ui.GroovyMain.processOnce(GroovyMain.java:650)
at groovy.ui.GroovyMain.run(GroovyMain.java:381)
at groovy.ui.GroovyMain.process(GroovyMain.java:367)
at groovy.ui.GroovyMain.processArgs(GroovyMain.java:126)
at groovy.ui.GroovyMain.main(GroovyMain.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:106)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:128)
Caught: groovyx.net.http.ResponseParseException: OK
groovyx.net.http.ResponseParseException: OK
at groovyx.net.http.HTTPBuilder$1.handleResponse(HTTPBuilder.java:495)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:1070)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:1044)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:515)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:434)
at groovyx.net.http.HTTPBuilder.request(HTTPBuilder.java:383)
at groovyx.net.http.HTTPBuilder$request.call(Unknown Source)
at sprint-snapshot.run(sprint-snapshot.groovy:11)
Caused by: groovy.json.JsonException: expecting '}' or ',' but got current char '"' with an int value of 34
The current character read is '"' with an int value of 34
expecting '}' or ',' but got current char '"' with an int value of 34
line number 1
index number 256
[{"id":417862,"name":"octokit.rb","full_name":"octokit/octokit.rb","owner":{"login":"octokit","id":3430433,"avatar_url":"https://avatars.githubusercontent.com/u/3430433?v=2","gravatar_id":"43f38795089d56a2a7092b7d0c71fa76","url":"h
................................................................................................................................................................................................................................................................^
at groovyx.net.http.ParserRegistry.parseJSON(ParserRegistry.java:280)
at groovyx.net.http.HTTPBuilder.parseResponse(HTTPBuilder.java:560)
at groovyx.net.http.HTTPBuilder$1.handleResponse(HTTPBuilder.java:489)
... 7 more
该错误似乎表明无效的JSON,但我已经确认响应确实有效,正如您对Github API所期望的那样。
更奇怪的是,如果我删除了授权'完全标头并发送请求未经验证,它工作正常:S
答案 0 :(得分:3)
最新版本的Groovy存在问题。我遇到过同样的问题。您的代码应该与2.3.0之前的Groovy版本一起使用。 (可选)您可以为HTTPBuilder尝试不同的默认JSONParserType。
请参阅 http://beta.groovy-lang.org/docs/groovy-2.3.0/html/gapi/groovy/json/JsonSlurper.html http://alfonsorv.com/instruct-groovy-httpbuilder-to-handle-a-json-response-with-wrong-content-type/
答案 1 :(得分:2)
这是我的代码解决方法
/*
* Normally we would use the method "request(GET, JSON)" to return a json result, but with the release
* of groovy 2.3.0, which included extensive changes to JSON parsing, the result returned from the
* Artifactory REST API call 'File List' could not be parsed by HTTPBuilder's default JSON parser.
*
* Specifying the content type as TEXT removes the parsing from the call. Code was added to parse the returned
* text into JSON using the more lenient 'LAX' parser.
*/
http.request( GET, TEXT ) {
//Since content type is text, we need to specify that a json response is acceptable.
headers.Accept = 'application/json'
headers.'User-Agent' = USER_AGENT
response.success = { respnse, reader ->
def jsonText = reader.text
def parser = new JsonSlurper().setType(JsonParserType.LAX)
def jsonResp = parser.parseText(jsonText)
//Add up the size of all the files in this directory
//
jsonResp.files.each {
directorySize = directorySize + Integer.parseInt("${it.size}".toString())
}
}
}
答案 2 :(得分:0)
def bufferedText = response.entity.content.getText( ParserRegistry.getCharset( response ) ).trim()
def result = new JsonSlurper().parseText( bufferedText )
答案 3 :(得分:-2)
def 'test hello resource'(){
when:
def info =""
// http.auth.basic('sysadmin', 'yax64smi')
// http.ignoreSSLIssues()//add for this issue Groovy:SSLPeerUnverifiedException: peer not authenticated new version (0.7.1) of HttpBuilder introduces method:ignoreSSLIssues()
http.request( GET,JSON ) {
uri.path = '/hello/'
//headers.'Authorization' = 'Basic c3lzYWRtaW46eWF4NjRzbWk='
//headers.'Authorization' = "Basic ${"username:password".bytes.encodeBase64().toString()}"
headers.'User-Agent' = 'Mozilla/5.0 Ubuntu/8.10 Firefox/3.0.4'
headers.'Content-Type' = 'application/json'
headers.Accept = 'application/json'
response.success = { resp ->
def parser = new JsonSlurper().setType(JsonParserType.LAX)
def jsonResptext = parser.parseText( resp.entity.content.getText())
println "PUT response status: ${resp.statusLine}"
assert resp.statusLine.statusCode == 200 ||resp.statusLine.statusCode ==201 ||resp.statusLine.statusCode ==202
info = resp.statusLine.statusCode
// def bufferedText = resp.entity.content.getText( ParserRegistry.getCharset( resp ) ).trim()
println 'Headers: -----------Response data: -----'
println "Content-Type: ${resp.headers.'Content-Type'}"
println jsonResptext
}
response.failure = { resp -> println "Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}" }
}
println "Result:\n"+info
then:
assert info ==200 || info ==201 || info ==202
}