ArcGIS GeoEvent处理器 - javax.xml.ws.soap.SOAPFaultException:解组错误

时间:2014-09-24 20:38:05

标签: java jaxb arcgis

背景

我正在使用wsimport来创建本质上是一个Java Web服务客户端,连接到返回数据集的.Net webservice(不幸的是)。更具体地说,我正在为ESRI ArcGIS Server 10.2的GeoEvent处理器套件开发一个项目(入站传输),但我认为这可以通过与JAXB和WSDL绑定相关的更一般的术语来回答。跟我在一起,因为我从大学毕业后没有接触过Java(10年以上)。

出于WSDL的目的,.Net DataSet是一种多态类型,其实际布局直到运行时才确定,在DataSet填充数据之后。当您想要将该Web服务与除.Net之外的任何内容一起使用时,这会导致问题。

经过一些研究后,我设法使用 wsimport 从webservice wsdl生成。然后,我能够将基于Web服务的结果作为DOM的基本概念验证程序放在一起,然后将该DOM作为节点列表。

参考:

我的wsimport看起来像这样(域名已被更改以保护无辜者):

C:\Development\ArcGIS\WSDL>wsimport -b http://www.w3.org/2001/XMLSchema.xsd -b xsd.xjb -keep -p com.somecompany.services -XadditionalHeaders http://services.somecompany.com/DataRetrieval.asmx?wsdl

问题

不幸的是,一旦我在ArcGIS GeoEvent处理器中实现,在我的概念验证中工作的相同代码库,从Web服务获取结果就失败了。我的项目是ArcGIS GeoEvent处理器将控制的OSGI包的一部分。下面的错误如GeoEvent Processor的Apache Karaf日志中所示。

根据错误,我的理解是我在wsimport中如何进行绑定存在问题,根据我上面列出的那些链接引用通用模式。看起来通用模式缺少对由wsimport生成的类存在的某些元素的定义。当我检查wsimport的输出时,这些类看起来是正确生成的。

由于发布限制,我没有包含WSDL,但如果需要,将包括在以后的响应中。

我想弄清楚

  • 如何解释此错误?
  • 为什么在ArcGIS GeoEvent处理器中运行时,在我的基本概念验证中用于访问Web服务的相同wsimport生成代码会失败?
  • 错误提及JAXB和SAX,我没有有意识地在概念验证或ArcGIS GeoEvent处理器项目中引用这些库中的任何一个。可能是Web服务的绑定/解组处理方式不同,ArcGIS GeoEvent处理器包装在JAXB / SAX中并且不是概念证明吗?
  • 我该怎么做才能解决这个问题?
      
        
    1. 使用不同的自定义xsd和xjb来说明Web服务的预期架构?我不确定如何做到这一点。
    2.   
    3. 使用 wsimport 以外的内容生成Web服务引用类?
    4.   
    5. 在Java环境中为ArcGIS GeoEvent处理器调整内容?
    6.   
    7. 其他选择?
    8.   
    9. 提交seppuku,那不是我的问题吗?
    10.   

错误

2014-09-23 16:10:14,365 | ERROR | ansport Listener | SomeInboundTransport             | 367 - com.somecompany.arcgis.geoevent.transport.inbound.somecompanyInboundTransport - 1.0.0 | Unable to call Webservice
javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"element"). Expected elements are <{http://services.somecompany.com/}complexType>,<{http://services.somecompany.com/}annotation>,<{http://services.somecompany.com/}redefine>,<{http://services.somecompany.com/}element>,<{http://services.somecompany.com/}include>,<{http://services.somecompany.com/}attributeGroup>,<{http://services.somecompany.com/}group>,<{http://services.somecompany.com/}notation>,<{http://services.somecompany.com/}import>,<{http://services.somecompany.com/}simpleType>,<{http://services.somecompany.com/}attribute> 
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:156)[120:org.apache.cxf.cxf-rt-frontend-jaxws:2.6.1]
    at com.sun.proxy.$Proxy198.getCompanyArcgisData(Unknown Source)[367:com.somecompany.arcgis.geoevent.transport.inbound.somecompanyInboundTransport:1.0.0]
    at com.somecompany.arcgis.geoevent.transport.inbound.SomeInboundTransport.callWebService(SomeInboundTransport.java:184)[367:com.somecompany.arcgis.geoevent.transport.inbound.somecompanyInboundTransport:1.0.0]
    at com.somecompany.arcgis.geoevent.transport.inbound.SomeInboundTransport.run(SomeInboundTransport.java:257)[367:com.somecompany.arcgis.geoevent.transport.inbound.somecompanyInboundTransport:1.0.0]
    at java.lang.Thread.run(Thread.java:722)[:1.7.0_17]
Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[com.sun.istack.SAXParseException2; lineNumber: 1; columnNumber: 651; unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"element"). Expected elements are <{http://services.somecompany.com/}complexType>,<{http://services.somecompany.com/}annotation>,<{http://services.somecompany.com/}redefine>,<{http://services.somecompany.com/}element>,<{http://services.somecompany.com/}include>,<{http://services.somecompany.com/}attributeGroup>,<{http://services.somecompany.com/}group>,<{http://services.somecompany.com/}notation>,<{http://services.somecompany.com/}import>,<{http://services.somecompany.com/}simpleType>,<{http://services.somecompany.com/}attribute>]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:425)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:362)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:339)
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.doUnmarshal(JAXBEncoderDecoder.java:784)[91:org.apache.cxf.cxf-rt-databinding-jaxb:2.6.1]
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.access$100(JAXBEncoderDecoder.java:97)[91:org.apache.cxf.cxf-rt-databinding-jaxb:2.6.1]
    at org.apache.cxf.jaxb.JAXBEncoderDecoder$1.run(JAXBEncoderDecoder.java:812)
    at java.security.AccessController.doPrivileged(Native Method)[:1.7.0_17]
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:810)[91:org.apache.cxf.cxf-rt-databinding-jaxb:2.6.1]
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:644)[91:org.apache.cxf.cxf-rt-databinding-jaxb:2.6.1]
    at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:157)[91:org.apache.cxf.cxf-rt-databinding-jaxb:2.6.1]
    at org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:108)[87:org.apache.cxf.cxf-api:2.6.1]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)[87:org.apache.cxf.cxf-api:2.6.1]
    at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:798)[87:org.apache.cxf.cxf-api:2.6.1]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1667)[118:org.apache.cxf.cxf-rt-transports-http:2.6.1]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1520)[118:org.apache.cxf.cxf-rt-transports-http:2.6.1]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1428)[118:org.apache.cxf.cxf-rt-transports-http:2.6.1]
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)[87:org.apache.cxf.cxf-api:2.6.1]
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:658)[118:org.apache.cxf.cxf-rt-transports-http:2.6.1]
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)[87:org.apache.cxf.cxf-api:2.6.1]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)[87:org.apache.cxf.cxf-api:2.6.1]
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:532)[87:org.apache.cxf.cxf-api:2.6.1]
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464)[87:org.apache.cxf.cxf-api:2.6.1]
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367)[87:org.apache.cxf.cxf-api:2.6.1]
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320)[87:org.apache.cxf.cxf-api:2.6.1]
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89)[119:org.apache.cxf.cxf-rt-frontend-simple:2.6.1]
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)[120:org.apache.cxf.cxf-rt-frontend-jaxws:2.6.1]
    ... 4 more
Caused by: com.sun.istack.SAXParseException2; lineNumber: 1; columnNumber: 651; unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"element"). Expected elements are <{http://services.somecompany.com/}complexType>,<{http://services.somecompany.com/}annotation>,<{http://services.somecompany.com/}redefine>,<{http://services.somecompany.com/}element>,<{http://services.somecompany.com/}include>,<{http://services.somecompany.com/}attributeGroup>,<{http://services.somecompany.com/}group>,<{http://services.somecompany.com/}notation>,<{http://services.somecompany.com/}import>,<{http://services.somecompany.com/}simpleType>,<{http://services.somecompany.com/}attribute>
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:642)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:254)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:249)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:116)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.childElement(Loader.java:101)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.childElement(StructureLoader.java:243)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:478)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:459)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:242)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:176)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:360)
    ... 28 more
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"element"). Expected elements are <{http://services.somecompany.com/}complexType>,<{http://services.somecompany.com/}annotation>,<{http://services.somecompany.com/}redefine>,<{http://services.somecompany.com/}element>,<{http://services.somecompany.com/}include>,<{http://services.somecompany.com/}attributeGroup>,<{http://services.somecompany.com/}group>,<{http://services.somecompany.com/}notation>,<{http://services.somecompany.com/}import>,<{http://services.somecompany.com/}simpleType>,<{http://services.somecompany.com/}attribute>
    ... 39 more

代码(摘录)

import com.somecompany.services.*; //generated by wsimport
import javax.xml.ws.*;
//...

private com.somecompany.services.DataRetrieval myWS;
private com.somecompany.services.DataRetrievalSoap port;

private byte[] callWebService(String userName, String pwd, long dataTimeFrame)
{
    try
    {
        myWS = new com.somecompany.services.DataRetrieval();

        port = myWS.getDataRetrievalSoap();
        com.somecompany.services.AuthSoapHeader mySoapHeader = new com.somecompany.services.AuthSoapHeader();
        mySoapHeader.setUserName(userName);

        //Hash the password then set it for the SOAP header
        String pwdHash = hashMD5(pwd);
        mySoapHeader.setPassword(pwdHash);
        Holder holder = new Holder<AuthSoapHeader>(mySoapHeader);

        Date endTime = new Date();
        Date startTime = new Date(endTime.getTime() - dataTimeFrame);
        XMLGregorianCalendar gcEndTime = dateToGregorianTime(endTime);
        XMLGregorianCalendar gcStartTime = dateToGregorianTime(startTime);

        GetCompanyArcgisDataResponse.GetCompanyArcgisDataResult companyData = port.getCompanyArcgisData(gcStartTime, gcEndTime, holder);

        if( ((AuthSoapHeader)holder.value).getError() != null)
        {
            log.error("Authentication to web services failed!");
            //OSGI stop service
            this.stop();
            return null;
        }else
            log.info("Authentication to web services successful.");

        //Convert the results to a java object and then to a byte array to send to the adapter
        Object companyDataAny = companyData.getAny();
        byte[] companyDataBytes = objectToBytes(companyDataAny);
        return companyDataBytes;

    }
    catch(Exception ex)
    {
        log.error("Unable to call Webservice", ex);
        //OSGI stop service
        this.stop();
        return null;
    }
}

环境细节

  • JDK 7u17(1.7.0_17)64位。 ArcGIS GeoEvent处理器正在使用此版本的JRE,因此我已锁定该版本以供执行。虽然在我意识到这一点之前我已经在1.7.0_51做了一些开发。
  • wsimport - JAX-WS RI 2.2.4-b01
  • ArcGIS Server 10.2
  • ArcGIS GeoEvent处理器扩展
  • Karaf(由ArcGIS Geovent处理器用于运行OSGI包)

1 个答案:

答案 0 :(得分:0)

这可能不是最好的答案,但这是我想出来的。

包装我的OSGI项目的ArcGIS GeoEvent处理器似乎正在对我在应用程序中引用的Web服务进行一些额外的绑定/解除绑定。我用来使用.Net(DataSet返回值)Web服务在Java中运行的解决方案对于GeoEvent处理器的包装器来说是不可接受的。

我的解决方案

最终我所做的是创建一个辅助.Net Web服务,该服务获取DataSet值并将它们转换为JSON,并返回JSON字符串。这消除了尝试从Web服务引用DataSet返回值时遇到的问题,现在我正在处理一个简单的JSON字符串。该JSON Web服务的 wsimport 变得顺畅,无需解决方法。我将新导入的Web服务文件隐藏到我的java项目中,现在没有问题。

有关C#DataSet到JSON的参考: