Grails RestClient 访问 POST 响应 XML
Grails RestClient accessing POST response XML
我正在使用 Groovy 的 RESTClient() 执行 POST,其中一些 XML 作为 URL 的有效载荷。我期望得到的回复是
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getNetworkSessionsForUsernameResponse
xmlns:ns2="http://webservice.foo.bar.net/">
<return>
<ip>1.1.1.1</ip>
<platform>112</platform>
<pop>ABC</pop>
<site>LIP</site>
<state>STATUS</state>
<userId>ID1234</userId>
</return>
</ns2:getNetworkSessionsForUsernameResponse>
</S:Body>
</S:Envelope>
我已经蜷缩到 URL 并且知道响应是正确的,所以返回的数据不是问题。我的问题是 RESTClient().post().getData()
returns 的格式。如果我这样做
def restClient = new RESTClient("www.someRestService.com", 'text/xml')
String soapRequest = """XML Payload..."""
def restClientResponse = restClient.post(body: soapRequest).getData()
log.info("RESPONSE: " + restClientResponse)
log.info("BODY: " + restClientResponse.Body.getNetworkSessionsForUsernameResponse.return.userId)
log.info("BODY T: " + restClientResponse.Body.getNetworkSessionsForUsernameResponse.return.userId.text())
log.info("NETWORK: " + restClientResponse.getNetworkSessionsForUsernameResponse.return.userId)
log.info("NETWORK T: " + restClientResponse.getNetworkSessionsForUsernameResponse.return.userId.text())
log.info("RETURN: " + restClientResponse.return.userId)
log.info("RETURN T: " + restClientResponse.return.userId.text())
log.info("USERID: " + restClientResponse.userId)
log.info("USERID T: " + restClientResponse.userId.text())
log.info("CHILDREN SIZE: " + restClientResponse.children().size())
log.info("CLASS: " + restClientResponse.getClass().getName())
记录的是:
RESPONSE: 1.1.1.1112ABCLIPSTATUSID1234
BODY:
BODY T:
NETWORK:
NETWORK T:
RETURN:
RETURN T:
USERID:
USERID T:
CHILDREN SIZE: 1
CLASS: groovy.util.slurpersupport.NodeChild
所以 getData()
似乎只是返回所有文本节点而不是解析的 XML 对象,我确定我在某处读到 getData()
解析 XML 使用 XMLSlurper()
。我阅读了 this 文章以及其他许多文章,这些文章看起来与我的问题完全一样,但给出的答案正是我正在做的,不是吗?我是否以完全错误的方式访问 restClientResponse
?
RESTClient
在内部与 XmlSlurper
执行的内部 XML 可能是 non namespace aware:
所以,
def restClientResponse = new XmlSlurper(false, false).parseText('''<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getNetworkSessionsForUsernameResponse
xmlns:ns2="http://webservice.foo.bar.net/">
<return>
<ip>1.1.1.1</ip>
<platform>112</platform>
<pop>ABC</pop>
<site>LIP</site>
<state>STATUS</state>
<userId>ID1234</userId>
</return>
</ns2:getNetworkSessionsForUsernameResponse>
</S:Body>
</S:Envelope>''')
println restClientResponse
def userId
userId = restClientResponse.Body.getNetworkSessionsForUsernameResponse.return.userId
println "${userId.size()}: [${userId.text()}]"
userId = restClientResponse.'S:Body'.'ns2:getNetworkSessionsForUsernameResponse'.return.userId
println "${userId.size()}: [${userId.text()}]"
以上结果:
1.1.1.1112ABCLIPSTATUSID1234
0: []
1: [ID1234]
(更改为 命名空间感知 XmlSlurper
结果恰恰相反)。
简答
我是个白痴!
中等答案
我正在处理的设计文档概述了预期从 REST 调用返回的 XML 是我包含在问题中的 XML,但实际上 XML 标签在真实响应中略有不同。 <ns2:getNetworkSessionsForUsernameResponse/>
实际上是 <ns2:getNetworkSessionsForIPResponse/>
;尽管我卷曲了 REST 客户端并比较了响应,但我对哪里出了问题感到沮丧。如果您遇到类似问题,请仔细检查,然后再次检查您实际使用的 XML。
我在 github 上浏览了 RESTClient
源代码,然后才弄清楚我做错了什么;参考@jalobaba 回答 XMLSlurper()
without any constructor args is used when parsing XML, so 'a non-validating and non-namespace-aware XmlSlurper' is created when an XML response is parsed
我正在使用 Groovy 的 RESTClient() 执行 POST,其中一些 XML 作为 URL 的有效载荷。我期望得到的回复是
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getNetworkSessionsForUsernameResponse
xmlns:ns2="http://webservice.foo.bar.net/">
<return>
<ip>1.1.1.1</ip>
<platform>112</platform>
<pop>ABC</pop>
<site>LIP</site>
<state>STATUS</state>
<userId>ID1234</userId>
</return>
</ns2:getNetworkSessionsForUsernameResponse>
</S:Body>
</S:Envelope>
我已经蜷缩到 URL 并且知道响应是正确的,所以返回的数据不是问题。我的问题是 RESTClient().post().getData()
returns 的格式。如果我这样做
def restClient = new RESTClient("www.someRestService.com", 'text/xml')
String soapRequest = """XML Payload..."""
def restClientResponse = restClient.post(body: soapRequest).getData()
log.info("RESPONSE: " + restClientResponse)
log.info("BODY: " + restClientResponse.Body.getNetworkSessionsForUsernameResponse.return.userId)
log.info("BODY T: " + restClientResponse.Body.getNetworkSessionsForUsernameResponse.return.userId.text())
log.info("NETWORK: " + restClientResponse.getNetworkSessionsForUsernameResponse.return.userId)
log.info("NETWORK T: " + restClientResponse.getNetworkSessionsForUsernameResponse.return.userId.text())
log.info("RETURN: " + restClientResponse.return.userId)
log.info("RETURN T: " + restClientResponse.return.userId.text())
log.info("USERID: " + restClientResponse.userId)
log.info("USERID T: " + restClientResponse.userId.text())
log.info("CHILDREN SIZE: " + restClientResponse.children().size())
log.info("CLASS: " + restClientResponse.getClass().getName())
记录的是:
RESPONSE: 1.1.1.1112ABCLIPSTATUSID1234
BODY:
BODY T:
NETWORK:
NETWORK T:
RETURN:
RETURN T:
USERID:
USERID T:
CHILDREN SIZE: 1
CLASS: groovy.util.slurpersupport.NodeChild
所以 getData()
似乎只是返回所有文本节点而不是解析的 XML 对象,我确定我在某处读到 getData()
解析 XML 使用 XMLSlurper()
。我阅读了 this 文章以及其他许多文章,这些文章看起来与我的问题完全一样,但给出的答案正是我正在做的,不是吗?我是否以完全错误的方式访问 restClientResponse
?
RESTClient
在内部与 XmlSlurper
执行的内部 XML 可能是 non namespace aware:
所以,
def restClientResponse = new XmlSlurper(false, false).parseText('''<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getNetworkSessionsForUsernameResponse
xmlns:ns2="http://webservice.foo.bar.net/">
<return>
<ip>1.1.1.1</ip>
<platform>112</platform>
<pop>ABC</pop>
<site>LIP</site>
<state>STATUS</state>
<userId>ID1234</userId>
</return>
</ns2:getNetworkSessionsForUsernameResponse>
</S:Body>
</S:Envelope>''')
println restClientResponse
def userId
userId = restClientResponse.Body.getNetworkSessionsForUsernameResponse.return.userId
println "${userId.size()}: [${userId.text()}]"
userId = restClientResponse.'S:Body'.'ns2:getNetworkSessionsForUsernameResponse'.return.userId
println "${userId.size()}: [${userId.text()}]"
以上结果:
1.1.1.1112ABCLIPSTATUSID1234
0: []
1: [ID1234]
(更改为 命名空间感知 XmlSlurper
结果恰恰相反)。
简答
我是个白痴!
中等答案
我正在处理的设计文档概述了预期从 REST 调用返回的 XML 是我包含在问题中的 XML,但实际上 XML 标签在真实响应中略有不同。 <ns2:getNetworkSessionsForUsernameResponse/>
实际上是 <ns2:getNetworkSessionsForIPResponse/>
;尽管我卷曲了 REST 客户端并比较了响应,但我对哪里出了问题感到沮丧。如果您遇到类似问题,请仔细检查,然后再次检查您实际使用的 XML。
我在 github 上浏览了 RESTClient
源代码,然后才弄清楚我做错了什么;参考@jalobaba 回答 XMLSlurper()
without any constructor args is used when parsing XML, so 'a non-validating and non-namespace-aware XmlSlurper' is created when an XML response is parsed