Java访问.NET WebService
有一对应用,A使用Java开发,B使用.NET开发;现要求B应用开发一个.NET WebService接口,将此接口URL登记到A应用中,当有消息产生时,A应用通过此接口向B应用报告。WebService开发出来后联调发现,即使有消息产生,B应用接口也未能拿到任何数据,甚至在接口代码中设置断点也无法捕获,查看IIS日志却发现A应用是有在调用接口的。由于A系统已经是一个产品化的应用,所以只能是调整B应用去适应它。
首先抓包,发现接口调用IIS直接报告HTTP 500错误,并包含“服务器未能识别 HTTP 标头 SOAPAction 的值”的错误信息,查资料,在接口声明前增加“[SoapDocumentMethod(Action="")]”后HTTP 500错误消失;
接着发现接口的输入参数全部为空,大致判断是WebService的SOAP消息格式不一致导致,将之前增加的部分修改为“[SoapDocumentMethod(Action="", Use=SoapBindingUse.Encoded, ParameterStyle=SoapParameterStyle.Wrapped, RequestNamespace="xxx", ResponseNamespace="xxx")]”,输入参数可以拿到;
但还发现返回的结果A应用却拿不到,仔细查看了一个Java范例的接口WSDL之后发现,原来.NET默认返回属性的名称是“<接口名>+Result”,但A应用却定义的名称是“return”,看到网上有文章介绍,再增加“[return: XmlElement("return")]”即可,但是实际测试发现无效,折腾了2-3个小时,才在M$的一篇文档上看到一句话“指定表示参数的 XML 元素的名称:将 XmlElement 属性应用于该参数,为该元素指定所需的名称,如果参数格式设置被设置为 Literal,还可以指定命名空间。如果参数格式设置被设置为 Encoded,则将 SoapElement 属性应用于该参数。”,又查了查VS的联机文档,改为“[return: SoapElement("return")]”,万事OK。
整个调整过程,接口内的代码一个字都没改,全部是在接口的声明上做文章,小小几个参数,搞了几个钟头。
以下附上最终的声明,实际使用要根据情况调整:
[WebMethod]
[SoapDocumentMethod(
Action="",
Use=SoapBindingUse.Encoded,
ParameterStyle=SoapParameterStyle.Wrapped,
RequestNamespace="xxx",
ResponseNamespace="xxx"
)
]
[return: SoapElement("return")]
public string xxxInterface(.....)
{...}
附一个不错的文档,看完之后对WebService又有了更深入的了解: 自定义 SOAP 消息的格式
发表评论