Grails wslite SOAP 参数导致解组错误

Grails wslite SOAP params result in Unmarshalling error

我正在尝试将 wslite (0.7.2.0) 与 Grails (2.4.4) 结合使用来使用 SOAP Web 服务。我能够让这个例子工作:

withSoap(serviceURL: 'http://www.holidaywebservice.com/Holidays/US/Dates/USHolidayDates.asmx') {
    def response = send(SOAPAction: 'http://www.27seconds.com/Holidays/US/Dates/GetMothersDay') {
        body {
            GetMothersDay(xmlns: 'http://www.27seconds.com/Holidays/US/Dates/') {
                year(2011)
            }
        }
    }

    println response.GetMothersDayResponse.GetMothersDayResult.text()
}

但是每当我尝试访问另一个需要参数的端点时,我都会收到 Unmarshall 异常。

我的代码:

withSoap(serviceURL: 'http://www.wcc.nrcs.usda.gov/awdbWebService/services?wsdl') {
    def response = send {
        body {
            getStations("xmlns": 'http://www.wcc.nrcs.usda.gov/ns/awdbWebService') {
                stateCds(Arrays.asList("OR"))
                logicalAnd(true)
            }
        }
    }

    response.getStationsResponse.return.each{resp->
        println resp
    }
}

异常:

Message
    soap:Client - Unmarshalling Error: unexpected element (uri:"http://www.wcc.nrcs.usda.gov/ns/awdbWebService", local:"stateCds").
    Expected elements are <{}elementCds>,<{}maxElevation>,<{}networkCds>,<{}heightDepths>,<{}ordinals>,<{}maxLongitude>,
    <{}minElevation>,<{}hucs>,<{}stateCds>,<{}minLatitude>,<{}countyNames>,<{}maxLatitude>,<{}minLongitude>,<{}stationIds>,<{}logicalAnd>

切换到 groovy-wslite-1.1.0 认为可能是插件的问题。不幸的是,尝试传递参数时会抛出相同的 Unmarshalling 异常。通过将原始 XML 传递给服务,我能够获得使用参数的请求。

问题是 stateCdslogicalAnd 元素不应命名空间。您应用于 getStations 元素的命名空间正在被这些子元素继承。

这是一个可以从 Groovy 控制台 运行 获得的工作示例:

@Grab(group='com.github.groovy-wslite', module='groovy-wslite', version='1.1.0')
import wslite.soap.*

def client = new SOAPClient('http://www.wcc.nrcs.usda.gov/awdbWebService/services')
def response = client.send {
    body {
        'awdb:getStations'("xmlns:awdb": 'http://www.wcc.nrcs.usda.gov/ns/awdbWebService') {
            stateCds('OR')
            logicalAnd(true)
        }
    }
}

assert !response.getStationsResponse.isEmpty()