Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9268298
  • 博文数量: 1669
  • 博客积分: 16831
  • 博客等级: 上将
  • 技术积分: 12594
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-25 07:23
个人简介

柔中带刚,刚中带柔,淫荡中富含柔和,刚猛中荡漾风骚,无坚不摧,无孔不入!

文章分类

全部博文(1669)

文章存档

2023年(4)

2022年(1)

2021年(10)

2020年(24)

2019年(4)

2018年(19)

2017年(66)

2016年(60)

2015年(49)

2014年(201)

2013年(221)

2012年(638)

2011年(372)

分类: LINUX

2011-11-28 15:41:34

java axis2 调用.net的webservice
下面是最近做的小例子,用Java Axis2作为客户端调用.net写的web服务。支持自定义的数据结构(这个不是那么简单……)。

准备:

1、下载axis2 ,注意,不要google “axis”,那个是旧版的,一定要google“axis2”,目前的最新版本是1.41。

2、Visual studio 2008,C#。 这个不用说什么了。

服务端:

在visual studio里写个hello world服务很简单,函数前加个[WebMethod]就可以。但是, 如果用到自定义的类,比如下面定义的person类作为GetUserInfoByPerson服务的参数:

view plaincopy to clipboardprint?
namespace WebService1  
{  
    public class Person  
    {  
        public string IdentityNumber  
        {  
            get { return m_IdentityNumber; }  
            set { m_IdentityNumber = value; }  
        }  
        private string m_IdentityNumber;  
    }  


namespace WebService1
{
    public class Person
    {
        public string IdentityNumber
        {
            get { return m_IdentityNumber; }
            set { m_IdentityNumber = value; }
        }
        private string m_IdentityNumber;
    }
}
这时要注意,直接按Ctrl+F5后生成的wsdl不包括Person的定义。

正确的做法是加一行
[SoapRpcMethod(Action = "", RequestNamespace = "", Use=SoapBindingUse.Literal)]

代码如下:

view plaincopy to clipboardprint?
[WebService(Namespace = "/")]  
public class Service1 : System.Web.Services.WebService  
{  
[WebMethod]  
[SoapRpcMethod(Action = "", RequestNamespace = "", Use=SoapBindingUse.Literal)]  
// 不加这一句,wsdl中就不生成Person类型  
public Person GetUserInfoByPerson(Person q)  
{  
Person p = new Person();  
p.IdentityNumber = q.IdentityNumber+"123";  
}  


[WebService(Namespace = "/")]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
[SoapRpcMethod(Action = "", RequestNamespace = "", Use=SoapBindingUse.Literal)]
// 不加这一句,wsdl中就不生成Person类型
public Person GetUserInfoByPerson(Person q)
{
Person p = new Person();
p.IdentityNumber = q.IdentityNumber+"123";
}
}
现在Ctrl+F5运行这个服务,假设地址是,那就可以在?WSDL里看到,Person的定义已经出现了。

客户端:

axis2有一个不错的quickstart教程。axis2目录下面samples\faulthandling这个例子值得参考,里面有详细的readme.txt和build.xml。

1、用axis2自带的wsdl2java工具生成代码框架:

%AXIS2_HOME%\bin\wsdl2java.bat -uri ?WSDL -u -o

这样会在target dir下生成一个目录,里面有现成的Person.java等代码。

2、写调用代码

在Eclipse里建好项目,加入axis2\lib目录下所有的jar包,把刚才生成的目录也拷进去。

然后可以写代码了:

view plaincopy to clipboardprint?
package example;  
import org.tempurl.*;  
public final class MyClient {  
  public static void main(String[] args) {  
  try {  
    Service1Stub service1Stub = new Service1Stub("");  
    service1Stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);  
    Service1 service1 = service1Stub;  
    GetUserInfoByPerson req = new GetUserInfoByPerson();  
    Person personReq = new Person();  
    personReq.setIdentityNumber("123");  
    req.setQ(personReq);  
    GetUserInfoByPersonResponse response = service1.GetUserInfoByPerson(req);  
    PersonE personResponse = response.getGetUserInfoByPersonResult();  
    System.out.println("ID = " + personResponse.getIdentityNumber());  
  } catch (Exception e) {  
  e.printStackTrace();  
}  
}  


package example;
import org.tempurl.*;
public final class MyClient {
  public static void main(String[] args) {
  try {
    Service1Stub service1Stub = new Service1Stub("");
    service1Stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);
    Service1 service1 = service1Stub;
    GetUserInfoByPerson req = new GetUserInfoByPerson();
    Person personReq = new Person();
    personReq.setIdentityNumber("123");
    req.setQ(personReq);
    GetUserInfoByPersonResponse response = service1.GetUserInfoByPerson(req);
    PersonE personResponse = response.getGetUserInfoByPersonResult();
    System.out.println("ID = " + personResponse.getIdentityNumber());
  } catch (Exception e) {
  e.printStackTrace();
}
}
}
注意这一句!service1Stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);

不做这个设置,一开始我怎么都调用失败,Axis2报告说HTTP send recv出错(记不清楚错误信息了)。用tcpmon查看调用服务时的tcp传输,发现.net的web server根本不接受axis2的soap包。(btw,tcpmon是个不错的工具啊。)

google了很久发现原因是,axis2在做http传输时采用了“chunked”模式,而.net的web server不支持。

“axis中使用的是HTTP/1.0协议,而.NET和axis2使用的是HTTP/1.1协议,后两者的区别在于.NET未使用ns1的命名空间前缀打包SOAP请求,且axis2使用了Content-Encoding: chunked头。 所以必须在axis2中设置一下。”

总结
阅读(3142) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~