未正确分析Groovy HTTPBuilder SOAP响应
我不明白为什么XmlSlurper显然没有处理结果未正确分析Groovy HTTPBuilder SOAP响应,soap,groovy,httpbuilder,Soap,Groovy,Httpbuilder,我不明白为什么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 =
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
}
}
因此,当输出变量时,XmlSlurper似乎正在丢弃SOAP内容并计算最内部的节点(),而不是实际导航到该节点。这是预期的行为吗
我无法使用httpBuilder找到更完整、更现代的SOAP调用和解析,因此我认为XML将是正确的内容类型。但看起来我只需要接受文本并自己解析主体,这看起来很蹩脚。使用httpBuilder处理SOAP响应有更好的方法吗?我建议打印响应的原始文本:
println "XML was ${resp.data.text}"
假设打印的XML行是您所期望的(虽然很奇怪,因为没有信封或正文节点),那么您应该能够从对XML的引用中删除区域。使用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()}"
另外,我只想指出SOAP1.2媒体类型是“application/SOAP+xml”
更新:
因此,当打印变量时,它看起来像XmlSlurper
out就是扔掉SOAP内容并计算最里面的节点
(),而不是实际导航到该节点。这是预期的吗
行为
是的,GPathResult的toString()方法只打印所有文本节点,而不是实际的元素或属性。使用HTTPBuilder,您可以通过以下方式打印原始响应文本:
println resp.data.text
我一直无法找到一个更完整、更现代的SOAP调用和
使用httpBuilder解析,所以我认为XML是正确的内容
类型。但看起来我只需要接受文本并解析
我自己的身体,看起来很瘸。有更好的处理肥皂的方法吗
httpBuilder的响应
ContentType.XML很好,问题在于web服务返回的SOAP响应是如何形成的。web服务将区域结果作为GetTerritoriesResult元素中的编码字符串发送回,而不是作为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}"
}
谢谢,这个评论很有帮助。从我读到的Scott Davis的Groovy食谱中,我认为text()是用于XmlParser的,而不是用于XmlSlurper的。但是${xml}和${xml.name()。你知道它为什么这样做吗?打印xml GPathResult时,它不显示标记,只显示文本内容,所以这就是你看到结果的原因。如果对GPathResult调用text(),它将返回一个包含该元素文本内容的字符串。在执行println之类的操作时,通常没有严格必要这样做,因为GPathResult上的toString()方法也会打印出元素的文本内容。
assert "Territories" == xml.name()
println "State were ${xml.State.text()}"
println "City were ${xml.Territory.City.text()}"
println "County were ${xml.Territory.County.text()}"
println resp.data.text
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}"
}