Вопрос по jaxb – WSImport генерирует конфликтующие типы XML для нескольких WSDL Dynamics CRM 4.0

9

В настоящее время я работаю с веб-сервисом Dynamics CRM 4.0. Первым делом я генерировал правильные классы с помощью wsimport дляJava/JAX-WS на основе WSDL веб-службы. При создании классов я получил несколько ошибок:

<code>[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
</code>

Строка 979 говорит нам:

<code><s:element name="RetrieveResponse">
    <s:complexType>
      <s:sequence>
        <s:element name="RetrieveResult" type="s3:BusinessEntity" />
      </s:sequence>
    </s:complexType>
  </s:element>
</code>

И строка 12274 дает нам:

<code><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>
</code>

Обе части находятся в одном пространстве имен. Оба будут сгенерированы как RetrieveResponse.class, и поэтому они сталкиваются. Я нашел решение этой проблемы - XML-файл привязки JAX-B:

<code><bindings node="//xsd:complexType[@name='RetrieveResponse']">
  <jaxb:class name="RetrieveResponseType"/>
</bindings>
</code>

Это работает (не уверен, если это правильный подход ..?) ..

Поэтому после этого мне удалось создать несколько успешных звонков в веб-службу, и это здорово!

Теперь возникает проблема: некоторые бизнес-объекты в динамике crm используют классPicklist, Этот тип объекта может быть запрошен с помощью службы метаданных:http://msdn.microsoft.com/en-us/library/bb890248.aspx

Поэтому следующее, что я сделал, опять-таки - генерация классов для службы метаданных на основе ее WSDL. Результат сгенерированных классов не такой, как мы, кроме. Например, он генерирует класс «com.microsoft.schemas.crm._2007.webservices.ExecuteResponse». Но этот класс также существует в том же пакете сгенерированных классов CrmService. Различия между двумя:

Метадатасервис ExecuteReponse:

<code>@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "response"
})
@XmlRootElement(name = "ExecuteResponse")
public class ExecuteResponse {

   @XmlElement(name = "Response")
   protected MetadataServiceResponse response;
etc...
</code>

CrmService ExecuteReponse:

<code>@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "response"
})
@XmlRootElement(name = "ExecuteResponse")
public class ExecuteResponse {

   @XmlElement(name = "Response", required = true)
   protected ResponseType response;
etc...
</code>

Теперь этот класс является лишь одним примером (другой примерCrmAuthenticationToken), который являетсяalmost Точная копия другого класса. Чтобы иметь возможность использовать одни и те же классы, я добавил пакетный суффикс к классам CrmService (отображается какprefix.). So now when I try to call the CrmService, I get the following exception:

<code>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
</code>

Лично я считаю странным, что разные классы с одинаковыми именами помещают в одну и ту же структуру пакета. Это означает, что вы никогда не сможете использовать 2 веб-сервиса одновременно.

Это Microsoft, ошибка WSimport или просто глупая ошибка в моем конце? Надеюсь, кто-нибудь может помочь мне с этой проблемой!

Спасибо за ваше время!

Ваш Ответ

1   ответ
1

import.

PickList и CRMAuthenticationToken звучат как пользовательские типы данных, и вы ожидаете, что они будут повторно использоваться от сервиса к сервису. Вы также ожидаете, что некоторые специфичные для CRM объекты (скажем, Клиент или Бизнес или Адрес) будут повторно использоваться от сервиса к сервису.

Это плохая манера со стороны Microsoft, что они определяют их по-разному для разных сервисов. Это затрудняет получение ответа одного сервиса и отправку его другому сервису.

Если бы службы использовали одну или несколько общих схем, вы могли бы сначала скомпилировать их, используя xjc. Затем вы могли бы предоставить так называемый файл эпизода для wsimport, чтобы он использовал эти классы вместо генерации новых. Увидетьгид метро, Это довольно загадка, я могу сказать вам по опыту, я столкнулся с ошибкой JAXB-829, xjc забывает генерировать атрибуты if-существующие в файле эпизода.

Что бы я ни делал, я компилировал каждый wsdl в свой собственный пакет и рассматривал сгенерированные классы как простые неразумные объекты передачи данных. Если бы я хотел отправить объект, который я только что получил из одного сервиса, во второй сервис, я бы конвертировал оба. Если это приводит к ужасно громоздкому коду или если вы хотите добавить логику к определенным сущностям, я предлагаю вам написать собственные подходящие классы моделей для сущностей, которыми вы хотите поделиться, и написать преобразователи в и из объектов DTO в веб-службах. пакеты, с которыми вы хотите их использовать.

Похожие вопросы