我目前正在使用 Dynamics CRM 4.0 Web 服务。我做的第一件事是根据 Web 服务的 WSDL 使用 wsimport for Java/JAX-WS 生成正确的类。在生成类时我遇到了一些错误:
[ERROR] A class/interface with the same name
"com.microsoft.schemas.crm._2007.webservices.RetrieveResponse" is already in use. Use a class customization to resolve this conflict.
line 979 of file://src/main/webapp/WEB-INF/classes/META-INF/wsdl/CrmServiceWsdl.wsdl
[ERROR] (Relevant to above error) another "RetrieveResponse" is generated from here.
line 12274 of file://src/main/webapp/WEB-INF/classes/META-INF/wsdl/CrmServiceWsdl.wsdl
第 979 行告诉我们:
<s:element name="RetrieveResponse">
<s:complexType>
<s:sequence>
<s:element name="RetrieveResult" type="s3:BusinessEntity" />
</s:sequence>
</s:complexType>
</s:element>
第 12274 行给了我们:
<s:complexType name="RetrieveResponse">
<s:complexContent mixed="false">
<s:extension base="tns:Response">
<s:sequence>
<s:element ref="s3:BusinessEntity" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
这两个部分位于同一命名空间中。两者都将生成为 RetrieveResponse.class,因此它们会发生冲突。我找到了解决这个问题的方法,即 JAX-B 绑定(bind) xml 文件:
<bindings node="//xsd:complexType[@name='RetrieveResponse']">
<jaxb:class name="RetrieveResponseType"/>
</bindings>
这有效(不确定这是否是正确的方法..?)..
在此之后,我成功创建了一些对网络服务的调用,这太棒了!
现在问题来了:Dynamics crm 中的某些业务实体使用类Picklist。可以使用元数据服务查询此类实体:http://msdn.microsoft.com/en-us/library/bb890248.aspx
所以我做的下一件事是再次根据元数据服务的 WSDL 生成元数据服务的类。生成的类的结果与我们不同。例如,它生成一个类“com.microsoft.schemas.crm._2007.webservices.ExecuteResponse”。但该类也存在于 CrmService 生成的类的完全相同的包中。两者之间的区别是:
元数据服务执行响应:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"response"
})
@XmlRootElement(name = "ExecuteResponse")
public class ExecuteResponse {
@XmlElement(name = "Response")
protected MetadataServiceResponse response;
etc...
CrmService 执行响应:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"response"
})
@XmlRootElement(name = "ExecuteResponse")
public class ExecuteResponse {
@XmlElement(name = "Response", required = true)
protected ResponseType response;
etc...
现在这个类只是一个示例(另一个示例是CrmAuthenticationToken),它几乎与另一个类完全相同。为了能够使用相同的类,我向 CrmService 类添加了包后缀(显示为前缀。)。 因此,现在当我尝试调用 CrmService 时,出现以下异常:
Two classes have the same XML type name "{http://schemas.microsoft.com/crm/2007/CoreTypes}CrmAuthenticationToken". Use @XmlType.name and @XmlType.namespace to assign different names to them.
this problem is related to the following location:
at com.microsoft.schemas.crm._2007.coretypes.CrmAuthenticationToken
at public com.microsoft.schemas.crm._2007.coretypes.CrmAuthenticationToken *prefix*.com.microsoft.schemas.crm._2007.coretypes.ObjectFactory.createCrmAuthenticationToken()
at *prefix*.com.microsoft.schemas.crm._2007.coretypes.ObjectFactory
this problem is related to the following location:
at *prefix*.com.microsoft.schemas.crm._2007.coretypes.CrmAuthenticationToken
at public javax.xml.bind.JAXBElement *prefix*.com.microsoft.schemas.crm._2007.webservices.ObjectFactory.createCrmAuthenticationToken(*prefix*.com.microsoft.schemas.crm._2007.coretypes.CrmAuthenticationToken)
at *prefix*.com.microsoft.schemas.crm._2007.webservices.ObjectFactory
我个人认为他们将具有相同名称的不同类放在同一个包结构中很奇怪。这意味着您永远不能同时使用 2 个网络服务..
这是 Microsoft、WSimport 错误还是只是我的一个愚蠢错误?希望有人能帮我解决这个问题!
感谢您的宝贵时间!
最佳答案
这是 Microsoft 的不一致,加上 wsimport 有点难以使用。
PickList 和 CRMAuthenticationToken 听起来像自定义数据类型,您希望这些数据能够在不同的服务之间得到重用。 您还希望某些特定于 CRM 的实体(例如,客户、业务或地址)能够在服务之间得到重用。
微软方面对不同的服务有不同的定义,这是不礼貌的行为。这使得很难获取一项服务的答案并将其发送到另一项服务。
如果服务共享一个或多个通用架构,您可以先使用 xjc 编译这些架构。然后,您可以向 wsimport 提供一个所谓的 Episode 文件,告诉它使用这些类而不是生成新的类。请参阅the metro guide 。这是一个很大的难题,我可以根据经验告诉你,我遇到了错误 JAXB-829,xjc 忘记在剧集文件中生成 if-exists 属性。
我要做的,是将每个 wsdl 编译到它自己的包中,并将生成的类视为简单的非智能数据传输对象。 如果我想将从一个服务检索到的对象发送到第二个服务,我会在两者之间进行转换。 如果这会导致代码非常笨重,或者如果您希望向某些实体添加逻辑,我建议您为您希望共享的实体编写自己的适当模型类,并编写与 Web 服务中的 DTO 对象之间的转换器您希望将它们与它们一起使用的软件包。
关于jaxb - WSImport 为多个 Dynamics CRM 4.0 WSDL 生成冲突的 XMLType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10515659/