首页 新闻 会员 周边

java调用.net web服务

0
悬赏园豆:100 [已关闭问题]

有一对应用,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 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 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 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来适应客户端。请各位帮忙。分不够再加

一的主页 | 初学一级 | 园豆:100
提问于:2010-07-01 13:01
< >
分享
其他回答(1)
0

更正:如果java端已经无法修改,那么大概我说的都是废话了,呵呵!

---------------------------------------------------------------------------------------------------

使用 metro 工具,将 .net 的 wcf 服务生成针对 java 平台的客户端调用类(java),这样你自己就不用维护分布式计算中间的信息交互过程了,包括编解码这样的琐碎事情。

具体的使用方法,可以通过搜索查找。总之,我有过这样的经历,其实.net 与java 交互很简单。搜索结果,比如:

http://chaizhixue2005.blog.sohu.com/139840107.html

To implement a Java client to communicate with the WCF server, you can follow the steps below:

1. Download METRO/WSIT from the home page of Metro: https://metro.dev.java.net.

2. Download Eclipse. We use Eclipse + Metro to develop Dynamsoft SCM Anywhere.

3. Install Metro by executing the command: java –jar metro-1_4.jar. The installation folder of Metro contains some documents, tools and samples. You can find the documents in the “docs” folder.

4. Use the C# project “WcfService1″ (provided in my WCF client and WCF service article) as the WCF server. Go to Property of the WCF project, and set the server port to one that is not occupied by other services. Here we used 8888 for example. In the “web.config” file, change the string “wsHttpBinding” to “basicHttpBinding”.

 5. This is the key step. We use the wsimport tool included in Metro to generate the Java client code. Create a file named “service1.xml” and copy the following code to the file:

<bindings
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    wsdlLocaption="http://localhost:8888/Service1.svc?wsdl"
    xmlns="http://java.sun.com/xml/ns/jaxws">
    <bindings node="wsdl:definitions">
        <enableAsyncMapping>true</enableAsyncMapping>
    </bindings>
</bindings>

The parameter “enableAsyncMapping” means generating the asynchronous method communicating to WCF server. Save this file, and execute the following command:

bin\wsimport -extension -keep -Xnocompile -b TestService.xml http://localhost:8888/Service1.svc?wsdl

Then you can find two new directories in Metro folder: “org” and “com”. They are the generated Java code.

6. Open Eclipse IDE, create a new Java project named “SimpleWCFClient”, and copy the two new directories “org” and “com” to the “src” folder of the project. Refresh the project, and you can find that some new code files are in the project.

7. Create a test class named “WCFTest” and write the following code to the file:

import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import org.tempuri.IService1;
import org.tempuri.Service1;

public class WCFTest {
    public static void main(String[] strArgs)
    {
        try
        {
            Service1 service1 = new Service1(new URL("http://localhost:8888/Service1.svc?wsdl"), new QName("http://tempuri.org/", "Service1"));
            IService1 port = service1.getBasicHttpBindingIService1();
            ((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8888/Service1.svc");
            int input = 100;
            String strOutput = port.getData(input);
            System.out.println(strOutput);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

8. Four .jar files need to be added to the Java project. You can get these files in the “lib” folder of Metro: webservices-api.jar, webservices-extra.jar, webservices-extra-api.jar, webservices-rt.jar. Then go to Property of the project and add these jars to the project.

9. Compile and run the Java project. If the Eclipse console outputs “You entered: 100″, congratulations, you are successful.

陛下 | 园豆:3938 (老鸟四级) | 2010-07-01 13:08
感谢您的回复。没找到解决方法。关键是java端已经不可能改了。但是我搞不明白的是明明是int类型,为什么java端发起的请求中被认为是复杂对象,所以进行了包装。
支持(0) 反对(0) | 园豆:100 (初学一级) | 2010-07-01 15:23
0

看看 AXIS 能不能解决你的问题。

http://ws.apache.org/axis/java/developers-guide.html

eaglet | 园豆:17139 (专家六级) | 2010-07-01 14:29
只能.net端修改来适应java端的调用。
支持(0) 反对(0) | 园豆:100 (初学一级) | 2010-07-01 15:21
@一: 实在不行,你在A 或 B 上写一个 java 的 web service ,A 访问这个java 的web service,这个 web service 再访问B 上的.net 的web service.由于这个 java 的 web service 是你自己做的,你可以随便改。
支持(0) 反对(0) eaglet | 园豆:17139 (专家六级) | 2010-07-02 07:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册