编辑:问题在于[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
。
除了自己编写代理类外,还有什么建议吗?
答案 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代理。
这有几个原因,其中最重要的是
ps:我对手动修改现有服务wsdls有很强的疑虑。如果wsdl确实是“问题”,那么这表明服务定义(即服务器端代码)或服务解释(即自动生成实用程序的选项)存在问题。避免手动操作服务合同。这样做就像在构建后修改IL字节代码一样。