我正在使用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,但如果需要,将包括在以后的响应中。
- 使用不同的自定义xsd和xjb来说明Web服务的预期架构?我不确定如何做到这一点。
- 使用 wsimport 以外的内容生成Web服务引用类?
- 在Java环境中为ArcGIS GeoEvent处理器调整内容?
- 其他选择?
- 提交seppuku,那不是我的问题吗?
醇>
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;
}
}
答案 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的参考: