当前位置:编程学习 > C#/ASP.NET >>

java调用.net的web service

有一对应用,A使用Java开发,B使用.NET开发;现要求B应用开发一个.NET WebService接口,将此接口URL登记到A应用中,当有消息产生时,A应用通过此接口向B应用报告。

WebService开发出来后联调发现,即使有消息产生,B应用接口也未能拿到任何数据,查看IIS日志却发现A应用是有在调用接口的。由于A系统已经是一个产品化的应用,所以只能是调整B应用去适应它。

首先抓包,发现接口调用IIS直接报告HTTP 500错误,错误信息如下:
System.InvalidOperationException: 请求格式无效: text/xml; charset=utf-8。
   在 System.Web.Services.Protocols.HttpServerProtocol.ReadParameters()
   在 System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

客户端抓包数据如下:
?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body>

<ns1:orderRelationUpdateNotify soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://soap.bossagent.vac.unicom.com">

<orderRelationUpdateNotifyRequest href="#id0"/></ns1:orderRelationUpdateNotify>

<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:OrderRelationUpdateNotifyRequest" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="http://req.sync.soap.bossagent.vac.unicom.com">
<recordSequenceId xsi:type="soapenc:string">20100701</recordSequenceId>
<userIdType href="#id1"/>
<userId xsi:type="soapenc:string">8618602392936</userId>
<serviceType xsi:type="soapenc:string">31</serviceType>
<spId xsi:type="soapenc:string">55255</spId>
<productId xsi:type="soapenc:string">2344101</productId>
<updateType href="#id2"/>
<updateTime xsi:type="soapenc:string">20100701120241</updateTime>
<updateDesc xsi:type="soapenc:string"></updateDesc>
<linkId xsi:type="soapenc:string"></linkId><content xsi:type="soapenc:string">qb</content>
<effectiveDate xsi:type="soapenc:string">20100701111700</effectiveDate>
<expireDate xsi:type="soapenc:string">20100701120237</expireDate>
<time_stamp xsi:type="soapenc:string">0701120241</time_stamp>
<encodeStr xsi:type="soapenc:string"></encodeStr>
</multiRef>

<multiRef id="id2" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="soapenc:int" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">2</multiRef>

<multiRef id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="soapenc:int" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">1</multiRef>

</soapenv:Body>
</soapenv:Envelope>

.net开发的web service如下:
    [WebService(Namespace = "http://temp.com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.None)]
    [SoapDocumentService(RoutingStyle = SoapServiceRoutingStyle.RequestElement)]
    [System.ComponentModel.ToolboxItem(false)]
    public class OrderRelationSync : System.Web.Services.WebService
    {
        [SoapRpcMethodAttribute(Action = "", Use = SoapBindingUse.Encoded)]
        [WebMethod]
        public OrderRelationUpdateNotifyResponse AcceptOrder(
            string recordSequenceID,
            int userIdType,
            string userId,
            string serviceType,
            string spId,
            string productId,
            int updateType,
            string updateTime,
            string updateDesc,
            string linkID,
            string content,
            string effectiveDate,
            string expireDate,
            string time_Stamp,
            string encodeStr)
        {
        }
客户端的soap请求中userIdType变成了这种格式:<userIdType href="#id1"/>,服务端的userIdType变量值要从其后的id为id1的<multiRef>1<multiRef>中取到,但是由于请求端不能修改,我不知道该如何修改.net web service来适应客户端。请各位帮忙。分不够再加 --------------------编程问答-------------------- 这个很简单,先通过接口把数据取出来,然后对数据经行封装。 --------------------编程问答-------------------- 也不知道你是怎么请求webservice的,简单的东西被你搞复杂了,
访问webservice最简单的方法就是url get方式了,你发送一个url请求也会 格式错误?
--------------------编程问答-------------------- WebService的跨语言就是个鸡肋,要真正做跨语言调用还是采用别的更好的技术吧。 --------------------编程问答--------------------
引用 3 楼 andot 的回复:
WebService的跨语言就是个鸡肋,要真正做跨语言调用还是采用别的更好的技术吧。


不妨举个例子说说其他方法?
比如说,我在上海的系统要获取远在北京的服务器数据,如气象台的天气预报,还有什么更好的方法吗? --------------------编程问答--------------------
引用楼主 thumb_cn 的回复:
  [WebService(Namespace = "http://temp.com/")]
  [WebServiceBinding(ConformsTo = WsiProfiles.None)]
  [SoapDocumentService(RoutingStyle = SoapServiceRoutingStyle.RequestElement)]


不太确定。

你的java客户端写死了?那么这些跟它匹配吗?


引用 1 楼 lester19872007 的回复:
这个很简单,先通过接口把数据取出来,然后对数据经行封装。


ws服务通过什么“接口”就能让“任意”预先开发的java客户端都顺从?

引用 3 楼 andot 的回复:
WebService的跨语言就是个鸡肋,要真正做跨语言调用还是采用别的更好的技术吧。

java开发跟.net开发只是“跨语言”?那么使用f#跟使用c#或者IronPhyshon之间不也是跨语言吗?怎么就非常轻松? --------------------编程问答-------------------- 就以你说的天气预报为例,先定义好天气信息的可序列化的类(或者用Map结构表示也行),然后定义好一个获取天气情况的方法,这方法可以在本地调用,也可以直接将其发布为服务让其他语言直接调用。

关于如何发布这样的可以跨语言跨平台的服务在这里有一个其.NET版本的视频教程:
https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032453967

另外这里还有一个视频教程是介绍该技术的Java版本的:
http://www.coolcode.org/?action=show&id=338
--------------------编程问答--------------------
引用 4 楼 keyouea 的回复:
不妨举个例子说说其他方法?
比如说,我在上海的系统要获取远在北京的服务器数据,如气象台的天气预报,还有什么更好的方法吗?


web service是为了跨平台,因此要仅仅实现最基本的、最傻瓜的协议,而不要轻易使用复杂的机制。

在更早,网站之间通信实际上只要访问网页并post数据就够了,在文档中把消息协议制定好,由双方各自解析。 --------------------编程问答--------------------
引用 5 楼 sp1234 的回复:
java开发跟.net开发只是“跨语言”?那么使用f#跟使用c#或者IronPhyshon之间不也是跨语言吗?怎么就非常轻松?


我说的跨语言是指真正的跨语言,可以跨.NET平台以外的语言。而WebService的跨语言是跨.NET平台之内的。 --------------------编程问答-------------------- 使用web service的好处是客户端可以通过wsdl来自动发现服务,比如互联网上发布10000个web service,不会搞出几千种所谓的私有协议出来!先有服务而后快速开发客户端,并且客户端可以自动适应服务端升级的情况。

但是你的情况,作为客户端竟然说“已经是一个产品化的应用”,这就比较难办了。因为vs中提供的工具只是帮助你去编译wsdl,当初可没有想到以那个次序来开发web service服务! --------------------编程问答--------------------
引用 8 楼 andot 的回复:
我说的跨语言是指真正的跨语言,可以跨.NET平台以外的语言。而WebService的跨语言是跨.NET平台之内的。


呵呵,跨java之内的语言、跨.net之内的语言,不叫跨语言。明白了,车轱辘话。 --------------------编程问答--------------------
引用 10 楼 sp1234 的回复:
引用 8 楼 andot 的回复:
我说的跨语言是指真正的跨语言,可以跨.NET平台以外的语言。而WebService的跨语言是跨.NET平台之内的。


呵呵,跨java之内的语言、跨.net之内的语言,不叫跨语言。明白了,车轱辘话。

看看webcast
貌似是集成了自己的传输协议,跨平台和跨语言的组件 --------------------编程问答-------------------- 解决办法如下:
1、找到你通过WSDL文件生成的服务端的CS代码文件,如“SyncNotifySPServiceServiceInterfaces.cs”文件;
2、找到其中的 private System.Nullable<int> updateTypeField; 
3、改成private int updateTypeField;
4、另一个userIdTypeField 字段同理;

基本上就可以了。应该是类型匹配的问题;

对方这个平台应该是“爱X信”公司的。针对各省平台开发时应先确认对方平台的开发厂家。因为不同厂家细节有区别,可能需要分别对待。

强烈建议:针对不同厂家开发的平台向对方发布不同的WEB服务端的地址。

这个解决方案技术层面的东西,你有兴趣自己研究一下吧~我这里不多叙述了。 --------------------编程问答-------------------- 1.方法前加上属性.

    <SoapRpcMethod(Action:="http://tempuri.org/GoodsQua", RequestNamespace:="http://www.tangs.com/T", ResponseNamespace:="http://www.tangs.com/T", Use:=SoapBindingUse.Literal)> _
    <WebMethod()> _
    Public Function GoodsQua(ByVal Var_GoodsColorSizeList As String) As String
            ...................
    End Function
2.不能返回DATASET,只能将DATASET组成数组返回.然后JAVA接收后再分解. --------------------编程问答-------------------- 你的问题是.net调用multiRef的问题 --------------------编程问答-------------------- 帮你顶 --------------------编程问答-------------------- 学习中 --------------------编程问答-------------------- 我也遇到这个问题啊,
客户端是linux写的,
服务器端用.net写WS接口,
奇怪的是调用时进入了方法,但是传进去的参数打印出来是空值,抓包出来确实是有东西的 --------------------编程问答-------------------- java代码调用没试过,但是.net是可以测试成功的
补充:.NET技术 ,  Web Services
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,