0

我不明白为什么 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, XMLPOST, 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>&lt;Territories&gt;&lt;State&gt;AZ&lt;/State&gt;&lt;ZipCode&gt;85203&lt;/ZipCode&gt;&lt;Territory&gt;&lt;City&gt;Mesa&lt;/City&gt;&lt;County&gt;Maricopa&lt;/County&gt;...&lt;/Territory&gt;&lt;/Territories&gt;
            </GetTerritoriesResult>
        </GetTerritoriesResponse>
    </soap:Body>
</soap:Envelope>

...

因此,当打印出变量时,看起来 XmlSlurper 正在丢弃 SOAP 内容并评估最里面的节点 (),而实际上并未导航到该节点。这是预期的行为吗?

我一直无法找到更完整和更现代的 SOAP 调用并使用 httpBuilder 进行解析,因此我认为 XML 将是正确的内容类型。但看起来我只需要接受 TEXT 并自己解析身体,这似乎很蹩脚。有没有更好的方法来使用 httpBuilder 处理 SOAP 响应?

4

1 回答 1

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 正在丢弃 SOAP 内容并评估最里面的节点 (),而实际上并未导航到该节点。这是预期的行为吗?

是的,GPathResult 的 toString() 方法只打印所有文本节点,而不是实际的元素或属性。使用 HTTPBuilder,您可以使用以下方法打印出原始响应文本:

println resp.data.text

我一直无法找到更完整和更现代的 SOAP 调用并使用 httpBuilder 进行解析,因此我认为 XML 将是正确的内容类型。但看起来我只需要接受 TEXT 并自己解析身体,这似乎很蹩脚。有没有更好的方法来使用 httpBuilder 处理 SOAP 响应?

ContentType.XML很好,问题在于您的 Web 服务返回的 SOAP 响应是如何形成的。Web 服务将Territories结果作为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}"
}
于 2011-10-20T00:26:27.460 回答