如何使用 HTTPBuilder 在 Groovy 中设置 GET-Response
How to set up a GET-Response in Groovy using HTTPBuilder
我的 YouTrack 服务器中存储了几个问题,我想提取这些问题并将信息打包到字符串中。
我已经使用过 RESTClient,但是我得到了错误的输出,因此想尝试使用 HttpBuilder 和格式化 JSON 中的 xml 响应来提取问题的不同方法。但是我还不知道如何在 Groovy 中做到这一点(可能是因为我缺少完整的 运行 示例):
经过 this website and this
我希望我的代码看起来像这样:
def http = new HTTPBuilder('http://www.MyYouTrackServer.com')
AuthenticateMe() // I need that, otherwise I cannot access my server
http.get( path : 'MyIssue-25',
contentType : JSON,
query : [???'] ) { resp, reader ->
....
// This gap has to be filled somehow,
// so that I have a JSONObject or JSONArray, I can work with.
....
}
println 'Response data: -----'
System.out << reader
println '\n--------------------'
}
String str; // this is the important String containing the data
欢迎任何建设性的建议、回答或评论。
响应将如下所示:
<issues>
<issue>
<comment created="1277899067543" text="is it something wrong?" author="root"/>
<field name="numberInProject"><value>0</value></field>
<field name="summary"><value>susjs</value></field>
<field name="priority"><value>1</value></field>
<field name="description"><value>at jsjsjsj.mps.E.java at line 12</value></field>
<field name="created"><value>1277392628191</value></field>
<field name="updated"><value>1277399118476</value></field>
<field name="reporterName"><value>root</value></field>
<field name="updaterName"><value>root</value></field>
<field name="state"><value>Submitted</value></field>
<field name="subsystem"><value>No subsystem</value></field>
<field name="fixedInBuild"><value>Next build</value></field>
<field name="permittedGroup"><value>All Users</value></field>
</issue>
</issues>
为了实现您的目标,您可以使用以下方法来处理 json:
import groovyx.net.http.HTTPBuilder
def http = new HTTPBuilder('http://www.MyYouTrackServer.com')
...
http.get( path : '/MyIssue-25',
contentType : 'application/json'
) { resp, reader ->
// inside reader you've your json object in `net.sf.json.JSONObject` instance
println reader
}
考虑到 get()
方法的 query
参数是可选的,此参数用于查询方法 url,如 https://twitter.com/search?q=asd
,对于这种情况,查询参数将是 query : [ q : 'asd' ]
.
所以回到代码,在 reader
对象中你有一个 net.sf.json.JSONObject
to work with, take a look at its API.
的实例
举个小例子,我在 http://localhost/index.json 有一个服务器,returns 跟随 json { "a":"a", "b": { "b1":"b1", "b2":"b2" }, "c":"c" }
使用下面的代码:
import groovyx.net.http.HTTPBuilder
def http = new HTTPBuilder('http://localhost')
http.get( path : '/index.json',
contentType : 'application/json'
) { resp, reader ->
// cast the object it's not necessary... I cast it
// to have the method suggestions by IDE
net.sf.json.JSONObject read = reader
println read.get("a") // prints "a"
println read.get("b").get("b1") // prints "b1"
//...
// you can also use this approach
println read.a // prints "a"
println read.b.b1 // prints "b1"
println read.b // prints [b1:b1, b2:b2]
}
更新
我又看了一遍你的问题,你的描述似乎是你试图阅读 YourTrack in a xml
format. To do so the approach it's really similar to the json
in this case the reader
object is an instance of GPathResult
中的问题,看看下面的示例,假设你的回答看起来像你输入的那个你的问题:
http = new HTTPBuilder('http://www.MyYouTrackServer.com')
http.get( path : '/MyIssue-25',
contentType : 'application/xml'
) { resp, reader ->
// since your response is an xml now in reader you've GPathResult
// and now some samples on how to work with the response:
// get the text of each <field>
def fields = reader.issue.field*.text();
fields.each {
print "$it " // prints 0 susjs 1 at jsjsjsj.mps.E.java at line 12 1277392628191 1277399118476 root root Submitted No subsystem Next build All Users numberInProject
}
// another sample... get the name attribute value for the <field> elements
def namesAttr = reader.issue.field*.@name
namesAttr.each {
print "$it " // prints numberInProject summary priority description created updated reporterName updaterName state subsystem fixedInBuild permittedGroup
}
// find the <field> value for element which has attribute name="state"
def field = reader.issue.'*'.findAll {
it.@name == 'state'
}
println field.text() // prints submitted
}
同样在这个 YourTrack
operation 中似乎有两个查询参数(project 和 max)可以使用它,您可以将查询参数添加到 get()
方法,即:query : [ max : '15' ]
.
希望这对您有所帮助,
以下是将 XML 响应转换为 JSON 对象的方法。注意:我在 XML 响应中添加了一个附加问题以更好地演示输出。
import groovy.util.XmlParser
import groovy.json.JsonBuilder
def text = '''
<issues>
<issue>
<comment created="1277899067543" text="is it something wrong?" author="root"/>
<field name="numberInProject"><value>0</value></field>
<field name="summary"><value>susjs</value></field>
<field name="priority"><value>1</value></field>
<field name="description"><value>at jsjsjsj.mps.E.java at line 12</value></field>
<field name="created"><value>1277392628191</value></field>
<field name="updated"><value>1277399118476</value></field>
<field name="reporterName"><value>root</value></field>
<field name="updaterName"><value>root</value></field>
<field name="state"><value>Submitted</value></field>
<field name="subsystem"><value>No subsystem</value></field>
<field name="fixedInBuild"><value>Next build</value></field>
<field name="permittedGroup"><value>All Users</value></field>
</issue>
<issue>
<comment created="1277899067543" text="does this work?" author="root"/>
<field name="numberInProject"><value>0</value></field>
<field name="summary"><value>susjs</value></field>
<field name="priority"><value>1</value></field>
<field name="description"><value>at jsjsjsj.mps.E.java at line 12</value></field>
<field name="created"><value>1277392628191</value></field>
<field name="updated"><value>1277399118476</value></field>
<field name="reporterName"><value>root</value></field>
<field name="updaterName"><value>root</value></field>
<field name="state"><value>Submitted</value></field>
<field name="subsystem"><value>No subsystem</value></field>
<field name="fixedInBuild"><value>Next build</value></field>
<field name="permittedGroup"><value>All Users</value></field>
</issue>
</issues>'''
def xml = new XmlParser().parseText(text)
def json = new JsonBuilder()
json xml.issue.inject([]) {list, issue ->
def map = [:]
map.comment = [
created: issue.comment["@created"][0],
text: issue.comment["@text"][0],
author: issue.comment["@author"][0],
]
issue.field.each {field ->
map[field['@name']] = field.value[0].children()[0]
}
list << map
return list
}
json.toString()
json.toString() 的漂亮格式化输出(感谢 TextMate)是这样的:
[
{
"comment": {
"author": "root",
"created": "1277899067543",
"text": "is it something wrong?"
},
"created": "1277392628191",
"description": "at jsjsjsj.mps.E.java at line 12",
"fixedInBuild": "Next build",
"numberInProject": "0",
"permittedGroup": "All Users",
"priority": "1",
"reporterName": "root",
"state": "Submitted",
"subsystem": "No subsystem",
"summary": "susjs",
"updated": "1277399118476",
"updaterName": "root"
},
{
"comment": {
"author": "root",
"created": "1277899067543",
"text": "does this work?"
},
"created": "1277392628191",
"description": "at jsjsjsj.mps.E.java at line 12",
"fixedInBuild": "Next build",
"numberInProject": "0",
"permittedGroup": "All Users",
"priority": "1",
"reporterName": "root",
"state": "Submitted",
"subsystem": "No subsystem",
"summary": "susjs",
"updated": "1277399118476",
"updaterName": "root"
}
]
我将 XML 转换为我认为更合理的数据表示形式。
我的 YouTrack 服务器中存储了几个问题,我想提取这些问题并将信息打包到字符串中。
我已经使用过 RESTClient,但是我得到了错误的输出,因此想尝试使用 HttpBuilder 和格式化 JSON 中的 xml 响应来提取问题的不同方法。但是我还不知道如何在 Groovy 中做到这一点(可能是因为我缺少完整的 运行 示例):
经过 this website and this
我希望我的代码看起来像这样:
def http = new HTTPBuilder('http://www.MyYouTrackServer.com')
AuthenticateMe() // I need that, otherwise I cannot access my server
http.get( path : 'MyIssue-25',
contentType : JSON,
query : [???'] ) { resp, reader ->
....
// This gap has to be filled somehow,
// so that I have a JSONObject or JSONArray, I can work with.
....
}
println 'Response data: -----'
System.out << reader
println '\n--------------------'
}
String str; // this is the important String containing the data
欢迎任何建设性的建议、回答或评论。
响应将如下所示:
<issues>
<issue>
<comment created="1277899067543" text="is it something wrong?" author="root"/>
<field name="numberInProject"><value>0</value></field>
<field name="summary"><value>susjs</value></field>
<field name="priority"><value>1</value></field>
<field name="description"><value>at jsjsjsj.mps.E.java at line 12</value></field>
<field name="created"><value>1277392628191</value></field>
<field name="updated"><value>1277399118476</value></field>
<field name="reporterName"><value>root</value></field>
<field name="updaterName"><value>root</value></field>
<field name="state"><value>Submitted</value></field>
<field name="subsystem"><value>No subsystem</value></field>
<field name="fixedInBuild"><value>Next build</value></field>
<field name="permittedGroup"><value>All Users</value></field>
</issue>
</issues>
为了实现您的目标,您可以使用以下方法来处理 json:
import groovyx.net.http.HTTPBuilder
def http = new HTTPBuilder('http://www.MyYouTrackServer.com')
...
http.get( path : '/MyIssue-25',
contentType : 'application/json'
) { resp, reader ->
// inside reader you've your json object in `net.sf.json.JSONObject` instance
println reader
}
考虑到 get()
方法的 query
参数是可选的,此参数用于查询方法 url,如 https://twitter.com/search?q=asd
,对于这种情况,查询参数将是 query : [ q : 'asd' ]
.
所以回到代码,在 reader
对象中你有一个 net.sf.json.JSONObject
to work with, take a look at its API.
举个小例子,我在 http://localhost/index.json 有一个服务器,returns 跟随 json { "a":"a", "b": { "b1":"b1", "b2":"b2" }, "c":"c" }
使用下面的代码:
import groovyx.net.http.HTTPBuilder
def http = new HTTPBuilder('http://localhost')
http.get( path : '/index.json',
contentType : 'application/json'
) { resp, reader ->
// cast the object it's not necessary... I cast it
// to have the method suggestions by IDE
net.sf.json.JSONObject read = reader
println read.get("a") // prints "a"
println read.get("b").get("b1") // prints "b1"
//...
// you can also use this approach
println read.a // prints "a"
println read.b.b1 // prints "b1"
println read.b // prints [b1:b1, b2:b2]
}
更新
我又看了一遍你的问题,你的描述似乎是你试图阅读 YourTrack in a xml
format. To do so the approach it's really similar to the json
in this case the reader
object is an instance of GPathResult
中的问题,看看下面的示例,假设你的回答看起来像你输入的那个你的问题:
http = new HTTPBuilder('http://www.MyYouTrackServer.com')
http.get( path : '/MyIssue-25',
contentType : 'application/xml'
) { resp, reader ->
// since your response is an xml now in reader you've GPathResult
// and now some samples on how to work with the response:
// get the text of each <field>
def fields = reader.issue.field*.text();
fields.each {
print "$it " // prints 0 susjs 1 at jsjsjsj.mps.E.java at line 12 1277392628191 1277399118476 root root Submitted No subsystem Next build All Users numberInProject
}
// another sample... get the name attribute value for the <field> elements
def namesAttr = reader.issue.field*.@name
namesAttr.each {
print "$it " // prints numberInProject summary priority description created updated reporterName updaterName state subsystem fixedInBuild permittedGroup
}
// find the <field> value for element which has attribute name="state"
def field = reader.issue.'*'.findAll {
it.@name == 'state'
}
println field.text() // prints submitted
}
同样在这个 YourTrack
operation 中似乎有两个查询参数(project 和 max)可以使用它,您可以将查询参数添加到 get()
方法,即:query : [ max : '15' ]
.
希望这对您有所帮助,
以下是将 XML 响应转换为 JSON 对象的方法。注意:我在 XML 响应中添加了一个附加问题以更好地演示输出。
import groovy.util.XmlParser
import groovy.json.JsonBuilder
def text = '''
<issues>
<issue>
<comment created="1277899067543" text="is it something wrong?" author="root"/>
<field name="numberInProject"><value>0</value></field>
<field name="summary"><value>susjs</value></field>
<field name="priority"><value>1</value></field>
<field name="description"><value>at jsjsjsj.mps.E.java at line 12</value></field>
<field name="created"><value>1277392628191</value></field>
<field name="updated"><value>1277399118476</value></field>
<field name="reporterName"><value>root</value></field>
<field name="updaterName"><value>root</value></field>
<field name="state"><value>Submitted</value></field>
<field name="subsystem"><value>No subsystem</value></field>
<field name="fixedInBuild"><value>Next build</value></field>
<field name="permittedGroup"><value>All Users</value></field>
</issue>
<issue>
<comment created="1277899067543" text="does this work?" author="root"/>
<field name="numberInProject"><value>0</value></field>
<field name="summary"><value>susjs</value></field>
<field name="priority"><value>1</value></field>
<field name="description"><value>at jsjsjsj.mps.E.java at line 12</value></field>
<field name="created"><value>1277392628191</value></field>
<field name="updated"><value>1277399118476</value></field>
<field name="reporterName"><value>root</value></field>
<field name="updaterName"><value>root</value></field>
<field name="state"><value>Submitted</value></field>
<field name="subsystem"><value>No subsystem</value></field>
<field name="fixedInBuild"><value>Next build</value></field>
<field name="permittedGroup"><value>All Users</value></field>
</issue>
</issues>'''
def xml = new XmlParser().parseText(text)
def json = new JsonBuilder()
json xml.issue.inject([]) {list, issue ->
def map = [:]
map.comment = [
created: issue.comment["@created"][0],
text: issue.comment["@text"][0],
author: issue.comment["@author"][0],
]
issue.field.each {field ->
map[field['@name']] = field.value[0].children()[0]
}
list << map
return list
}
json.toString()
json.toString() 的漂亮格式化输出(感谢 TextMate)是这样的:
[
{
"comment": {
"author": "root",
"created": "1277899067543",
"text": "is it something wrong?"
},
"created": "1277392628191",
"description": "at jsjsjsj.mps.E.java at line 12",
"fixedInBuild": "Next build",
"numberInProject": "0",
"permittedGroup": "All Users",
"priority": "1",
"reporterName": "root",
"state": "Submitted",
"subsystem": "No subsystem",
"summary": "susjs",
"updated": "1277399118476",
"updaterName": "root"
},
{
"comment": {
"author": "root",
"created": "1277899067543",
"text": "does this work?"
},
"created": "1277392628191",
"description": "at jsjsjsj.mps.E.java at line 12",
"fixedInBuild": "Next build",
"numberInProject": "0",
"permittedGroup": "All Users",
"priority": "1",
"reporterName": "root",
"state": "Submitted",
"subsystem": "No subsystem",
"summary": "susjs",
"updated": "1277399118476",
"updaterName": "root"
}
]
我将 XML 转换为我认为更合理的数据表示形式。