我不明白为什么XmlSlurper显然没有处理结果。
import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
def String WSDL_URL = ...
def http = new HTTPBuilder( WSDL_URL , ContentType.XML )
String soapEnvelope =
"""<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<GetTerritories xmlns="...">
<State>AZ</State>
<ZipCode>85203</ZipCode>
</GetTerritories>
</soap12:Body>
</soap12:Envelope>"""
http.request( POST, XML ) {
headers."Content-Type" = "application/soap+xml; charset=utf-8"
headers."Accept" = "application/soap+xml; charset=utf-8"
body = soapEnvelope
response.success = { resp, xml ->
println "XML was ${xml}"
println "Territories were ${xml.Territories}"
println "State were ${xml.Territories.State}"
println "City was ${xml.Territories.Territory.City}"
println "County was ${xml.Territories.Territory.County}"
}
response.failure = { resp, xml ->
xml
}
}
导致
XML was <Territories><State>AZ</State><ZipCode>85203</ZipCode><Territory><City>Mesa</City><County>Maricopa</County>...</Territory></Territories>
Territories were
State were
City was
County was
更新:感谢John Wagenleitner的洞察力,我做了一些挖掘。
当我添加断言时,我发现了一个问题:
assert "Territories" == xml.name()
| | |
| | Envelope
| <Territories><State>AZ</State><ZipCode>85203</ZipCode</Territories>
false
将请求参数从POST, XML
更改为POST, TEXT
具有以下意义:
XML was <?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetTerritoriesResponse xmlns="...">
<GetTerritoriesResult><Territories><State>AZ</State><ZipCode>85203</ZipCode><Territory><City>Mesa</City><County>Maricopa</County>...</Territory></Territories>
</GetTerritoriesResult>
</GetTerritoriesResponse>
</soap:Body>
</soap:Envelope>
...
因此,当打印出变量时,看起来XmlSlurper正在抛弃SOAP内容并评估最内层节点(),而实际上并未导航到该节点。这是预期的行为吗?
我一直无法使用httpBuilder找到更完整和现代的SOAP调用和解析,因此我假设XML是正确的内容类型。但看起来我只需要接受TEXT并自己解析身体,这似乎很蹩脚。有没有更好的方法来处理使用httpBuilder的SOAP响应?
答案 0 :(得分:1)
我建议打印回复的原始文本:
println "XML was ${resp.data.text}"
假设打印的XML行符合您的预期(虽然没有Envelope或Body节点,因此很奇怪),那么您应该能够从对xml的引用中删除 Territories 。使用XmlSlurper解析时,根节点是GPathResult。
assert "Territories" == xml.name()
println "State were ${xml.State.text()}"
println "City were ${xml.Territory.City.text()}"
println "County were ${xml.Territory.County.text()}"
另外,只是想指出SOAP 1.2媒体类型是“application / soap + xml”。
<强>更新强>
当打印变量时,它看起来像XmlSlurper out,扔掉SOAP东西并评估最里面的节点 ()而实际上并没有导航到该节点。这是预期的 行为?
是的,GPathResult的toString()方法只打印所有文本节点,而不是实际的元素或属性。使用HTTPBuilder,您可以使用以下方法打印出原始响应文本:
println resp.data.text
我一直无法找到更完整和现代的SOAP调用 使用httpBuilder解析,所以我假设XML将是正确的内容 类型。但看起来我只需要接受TEXT并解析它 身体自己,这似乎很蹩脚。有没有更好的方法来处理SOAP 用httpBuilder做出回应?
ContentType.XML 很好,问题在于如何形成Web服务返回的SOAP响应。网络服务正在 GetTerritoriesResult 元素中将 Territories 结果作为编码字符串发回,而不是作为其中的一部分HTTPBuilder自动为您解析的实际XML响应(这不是HTTPBuilder处理它的方式的问题)。因为您真正想要的数据是在该编码字符串中,您需要自己解析 GetTerritoriesResult 的文本节点。
response.success = { resp, xml ->
println "XML was ${resp.data.text}"
def territories = new XmlSlurper().parseText(
xml.Body.GetTerritoriesResponse.GetTerritoriesResult.text()
)
println "State were ${territories.State}"
println "City was ${territories.Territory.City}"
println "County was ${territories.Territory.County}"
}