Grails RestClient访问POST响应XML

时间:2015-03-27 16:24:32

标签: xml rest grails groovy

我正在使用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>

我已经卷入了网址并知道响应是正确的,因此回复的数据不是问题。我的问题是RESTClient().post().getData()返回的格式。如果我做

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()使用XMLSlurper()解析XML。我在许多其他文章中看过this文章,这看起来与我的问题完全一样,但给出的答案正是我正在做的不是吗?我是以完全错误的方式访问restClientResponse吗?

2 个答案:

答案 0 :(得分:1)

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结果正好相反。

答案 1 :(得分:0)

简短回答

我是个白痴!

中等回答

我正在研究的设计文档概述了从REST调用中预期的XML是我在问题中包含的XML,但实际上其中一个XML标记在实际响应中略有不同。 <ns2:getNetworkSessionsForUsernameResponse/>实际上是<ns2:getNetworkSessionsForIPResponse/>;即使我把REST客户端卷起来,并且比较了我在雪中失明的反应,我对于出了什么问题感到沮丧。如果你有类似的问题仔细检查,那么再次仔细检查你实际使用的XML。

在我弄清楚我做错了之前,我在github上搜索了RESTClient源代码;在参考@jalopaba时,在解析XML时使用XMLSlurper()而没有任何构造函数args,因此&#39; 一个非验证和非命名空间的XmlSlurper &#39;在XML响应为parsed

时创建