Вызов службы WCF из Java - PullRequest
1 голос
/ 10 июня 2010

РЕДАКТИРОВАТЬ: проблема была с атрибутами [MessageHeader] в классе ResponseMessage; Metro / JAX-WS не способен обрабатывать эти атрибуты. Изменение их на [MessageBodyMember] решило проблему.


Как видно из названия, мне нужно получить код Java 1.5 для вызова веб-службы WCF. Я загрузил и использовал Metro для создания прокси-классов Java, но они не генерируют то, что я ожидаю, и я считаю, что это из-за WSDL, который генерирует служба WCF.

Мои классы WCF выглядят так (для краткости полный код опущен):

public class TestService : IService
{
  public TestResponse DoTest(TestRequest request)
  {
    TestResponse response = new TestResponse();

    // actual testing code...

    response.Result = ResponseResult.Success;

    return response;
  }
}

public class TestResponse : ResponseMessage
{
  public bool TestSucceeded { get; set; }
}

public class ResponseMessage
{
  [MessageHeader]
  public ResponseResult Result { get; set; }

  [MessageHeader]
  public string ResponseDesc { get; set; }

  [MessageHeader]
  public Guid ErrorIdentifier { get; set; }
}

public enum ResponseResult
{
  Success,
  Error,
  Empty,
}

и полученный WSDL (при просмотре http://localhost/TestService?wsdl=wsdl0) выглядит так:

<xsd:element name="TestResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" name="TestSucceeded" type="xsd:boolean" /> 
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="ErrorIdentifier" type="q1:guid" xmlns:q1="http://schemas.microsoft.com/2003/10/Serialization/" /> 
<xsd:simpleType name="ResponseResult">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Error" /> 
<xsd:enumeration value="Success" /> 
<xsd:enumeration value="EmptyResult" /> 
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="ResponseResult" nillable="true" type="tns:ResponseResult" /> 
<xsd:element name="Result" type="tns:ResponseResult" /> 
<xsd:element name="ResultDesc" nillable="true" type="xsd:string" />

...

<xs:element name="guid" nillable="true" type="tns:guid" /> 
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" /> 
</xs:restriction>
</xs:simpleType>

Сразу же я вижу проблему с этим WSDL: TestResponse не содержит свойств, унаследованных от ResponseMessage. Так как этот сервис всегда работал в Visual Studio, я никогда не спрашивал об этом раньше, но, может быть, это может вызвать мою проблему?

Во всяком случае, когда я запускаю Metro's wsimport.bat в службе, генерируется следующее сообщение об ошибке:

[WARNING] src-resolve.4.2: Error resolving component 'q1:guid'

и в выводимой версии Java TestResponse отсутствуют какие-либо свойства из ResponseMessage.

Я немного взломал WSDL и изменил ErrorIdentifier на тип xsd:string, что убирает сообщение о разрешении типа GUID, но я до сих пор не получил ни одного из свойств ResponseMessage.

Наконец, я изменил WSDL, чтобы включить 3 свойства из ResponseMessage в TestResponse, и, конечно, конечный результат заключается в том, что сгенерированный файл .java содержит их. Однако когда я на самом деле вызываю службу WCF из Java, эти 3 свойства всегда null.

Какой-нибудь совет, кроме написания прокси-классов сам?

Ответы [ 3 ]

3 голосов
/ 11 июня 2010

Немного #% $ ^ @!изменил атрибуты [MessageBodyMember] в свойствах ResponseMessage на [MessageHeader], не сказав никому.Я изменил их обратно на [MessageBodyMember], заново сгенерировал прокси-классы и все работает правильно.

После того, как я закончил интеграцию, я буду делать различия в CVS, чтобы найти ответственного за него, а потом они будут страдатьГНЕВ.

0 голосов
/ 10 июня 2010

Хм, я не имею в виду быть glib или отвергать нативные решения Java, но когда дело доходит до стека Wcf, лучший совет, как правило, использовать стек Wcf.

Более конкретно: сгенерируйте клиент CLR Wcf [на выбранном языке, автоматически генерируйте клиент с помощью VS или svcutil для статической wsdl или конечной точки службы], а затем вызовите этот прокси-сервер CLR через некоторое взаимодействие Java-CLR.

Для этого есть несколько причин, не в последнюю очередь

  • Немедленное соответствие [Wcf для Wcf]
  • Гибкость [вполне разумно ожидать, что ваша удаленная служба изменит или использует сложные протоколы связи, такие как шифрование на уровне сообщений, вы хотите, чтобы ваш клиент изменился так же легко, как и служба]

ps: у меня есть серьезные опасения по поводу изменения существующего сервиса wsdls вручную. Если wsdl действительно является «проблемой», то это указывает либо на проблему с определением сервиса [т.е. кодом на стороне сервера], либо с интерпретацией сервиса [т.е. опцией утилиты автогенерации]. Избегайте ручных манипуляций с контрактами на обслуживание. Это похоже на изменение байтового кода IL после сборки.

0 голосов
/ 10 июня 2010

Эта проблема не имеет ничего общего с Java, а только с генерируемым WSDL.

Почему вы не используете [DataContract] и [DataMember] в ваших классах TestResponse и ResponseMessage?Попробуйте и посмотрите, работает ли он.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...