从Java调用WCF服务

时间:2010-06-10 14:06:15

标签: c# wcf

编辑:问题在于[MessageHeader]类中的ResponseMessage属性; Metro / JAX-WS似乎无法处理这些属性。将它们更改为[MessageBodyMember]解决了这个问题。


正如标题所说,我需要获得一些Java 1.5代码来调用WCF Web服务。我已经下载并使用Metro生成Java代理类,但它们没有生成我期望的内容,我相信这是因为WCF服务生成的WSDL。

我的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的wsimport.bat时,会生成以下错误消息:

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

,输出的TestResponse Java版本缺少ResponseMessage的任何属性。

我稍微破解了WSDL,并将ErrorIdentifier更改为xsd:string,这使得解析GUID类型的消息消失了,但我仍然没有得到任何{{1} }}的属性。

最后,我更改了WSDL以在ResponseMessage中包含来自ResponseMessage的3个属性,当然最终结果是生成的.java文件包含它们。但是,当我实际从Java调用WCF服务时,这3个属性始终是TestResponse

除了自己编写代理类外,还有什么建议吗?

3 个答案:

答案 0 :(得分:3)

一些#%$ ^ @!在不告诉任何人的情况下,将[MessageBodyMember]属性的ResponseMessage属性更改为[MessageHeader]。我将它们更改回[MessageBodyMember],重新生成代理类,一切正常。

一旦我完成了整合,我将做CVS差异以找到负责人,然后他们应该让我的伤害。

答案 1 :(得分:0)

这个问题与Java无关,只与生成的WSDL有关。

为什么不在TestResponse和ResponseMessage类上使用[DataContract][DataMember]?试试看,看看它是否有效。

答案 2 :(得分:0)

嗯,我不是故意要搞笑或拒绝Java本地解决方案,但是当谈到Wcf堆栈时,最好的建议通常是使用 Wcf堆栈。 / p>

更重要的是:生成一个CLR Wcf客户端[选择语言通过VS自动生成客户端或svcutil对静态wsdl或服务端点]然后通过一些Java-CLR互操作调用此CLR代理。

这有几个原因,其中最重要的是

  • 立即遵守[Wcf为Wcf]
  • 灵活性[期望您的远程服务更改或利用复杂的通信协议(例如消息级加密,您希望客户端像服务一样轻松地更改)并非不合理]

ps:我对手动修改现有服务wsdls有很强的疑虑。如果wsdl确实是“问题”,那么这表明服务定义(即服务器端代码)或服务解释(即自动生成实用程序的选项)存在问题。避免手动操作服务合同。这样做就像在构建后修改IL字节代码一样。