初学者学习webservice JAVA调用.NET篇

java调用可能有很多方法,我研究了其中的两种。两种均为apache的项目:soap方式以及axis模式。研究的目的是希望能够与某公司的数据库和我们自己平台的数据库及时同步。但是我们不能够直接调用对方数据库的数据,对方的程序就是使用.NET做的,提供了对于我们调用所需要的webservice。对于初学者来说,webservice的是一个很模糊的概念。我的一个朋友最早的时候给我做了一个比喻,就是把webservice当作javabean对待,你只要知道实现你所需要的结果需要传递什么参数给webservice,然后就接收相应的返回结果。知道这些后相信看这篇文章的读者能够有对webservice一点模型化的认识。举个简单的例子:用C#编写一个webservice,代码如程序1所示,保存成asmx格式。然后放到IIS网站的根目录下面(在这个环节我曾经出现了一个问题,就是我配置的计算机系统为windows2003企业版,装完后没有配置IIS,就直接把VS2003装上了,然后再配置IIS,将会出现IIS认为你没有.NET环境的问题,然后我手动在IIS下面加了Web 服务扩展如图1(添加的扩展文件为C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/aspnet_isapi.dll),并且允许了。

重起IIS后毛病依然存在。后来查找资料找到解决方法,先在.net的命令行方式下敲入aspnet_regiis –i然后回车。我的问题就解决了。

1

2

在浏览器中访问你自己的webservice程序,

 

<%@ WebService Language="C#" Class="Example1" %>

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Diagnostics;

using System.Web;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.Web.Services.Description;

[WebService(Namespace="urn:www.routon.com.cn")]

public class Example1 {

[SoapDocumentMethodAttribute(Action="",

RequestNamespace="urn:www.routon.com.cn",

RequestElementName="sayHello",

ResponseNamespace="urn:www.routon.com.cn",

ResponseElementName="arithmeticMeanResponse",

Use=SoapBindingUse.Encoded)]

[ WebMethod ]

public string sayHello(string name) {

return "Hello " + name;

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

程序1

WSDL文件位置为http://localhost/HelloWorld.asmx?WSDL  具体内容如下。

  <?xml version="1.0" encoding="utf-8" ?>

- <wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:www.routon.com.cn" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="urn:www.routon.com.cn" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

- <wsdl:types>

- <s:schema targetNamespace="urn:www.routon.com.cn">

- <s:complexType name="sayHello">

- <s:sequence>

  <s:element minOccurs="1" maxOccurs="1" name="name" type="s:string" />

  </s:sequence>

  </s:complexType>

- <s:complexType name="arithmeticMeanResponse">

- <s:sequence>

  <s:element minOccurs="1" maxOccurs="1" name="sayHelloResult" type="s:string" />

  </s:sequence>

  </s:complexType>

  </s:schema>

  </wsdl:types>

- <wsdl:message name="sayHelloSoapIn">

  <wsdl:part name="parameters" type="tns:sayHello" />

  </wsdl:message>

- <wsdl:message name="sayHelloSoapOut">

  <wsdl:part name="parameters" type="tns:arithmeticMeanResponse" />

  </wsdl:message>

- <wsdl:portType name="Example1Soap">

- <wsdl:operation name="sayHello">

  <wsdl:input message="tns:sayHelloSoapIn" />

  <wsdl:output message="tns:sayHelloSoapOut" />

  </wsdl:operation>

  </wsdl:portType>

- <wsdl:binding name="Example1Soap" type="tns:Example1Soap">

  <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />

- <wsdl:operation name="sayHello">

  <soap:operation soapAction="" style="document" />

- <wsdl:input>

  <soap:body use="encoded" namespace="urn:www.routon.com.cn" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />

  </wsdl:input>

- <wsdl:output>

  <soap:body use="encoded" namespace="urn:www.routon.com.cn" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />

  </wsdl:output>

  </wsdl:operation>

  </wsdl:binding>

- <wsdl:service name="Example1">

- <wsdl:port name="Example1Soap" binding="tns:Example1Soap">

  <soap:address location="http://localhost/HelloWorld.asmx" />

  </wsdl:port>

  </wsdl:service>

  </wsdl:definitions>

WSDL文件是对于提供的webservice的一种标准化描述。对于使用Axis方法调用有相当大的作用。部署好能够正常运行的webservice后,就要开始我们的工作啦-------JAVA程序。

SOAP方法

对于编写基于soap方法能够调用.NETJAVA程序,你必须有一下几个工具:

1、  操作系统(哈哈)

2、  JDK(我使用的是j2sdk1.4.2

3、  Soap.jar(我使用的soap-2_3_1,下载到的包中soap-2_3_1/docs/路径下面有文档可查,别忘了)

4、  Mail.jar(我用的是啥版本的忘了,因为我们自己的系统上面有,我就直接导进来了)

5、  集成开发环境(我的是Eclipse3.1.1

eclipse中创建工程,导入soap.jarmail.jar,以及其他相关包,这里我就不一一复述了。建立一个类文件,程序为:

    public static void main(String args[]) throws MalformedURLException, SOAPException {

//          doLaiheng("hahaha");

        URL url = new URL("http://127.0.0.1/SayHelloto.asmx");

        // 参数名

        String name = "laiheng";

        Call call = new Call();

        call.setTargetObjectURI("urn:www.routon.com.cn");

        // 下面为方法名

        call.setMethodName("sayHello");

        //call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);

        Vector params = new Vector();

        params.addElement(new Parameter("name", String.class, name, null));

        call.setParams(params);

        System.out.print("远程的服务器对你说: ");

        Response resp = call.invoke(url, "");

        if (resp.generatedFault()) {

               Fault fault = resp.getFault();

               System.out.println("/nOuch, the call failed: ");

               System.out.println(" Fault Code = " + fault.getFaultCode());

               System.out.println(" Fault String = " + fault.getFaultString());

        } else {

               Parameter result = resp.getReturnValue();

               System.out.print(result.getValue());

               System.out.println();

        }

}

如果正常的话,控制台将显示“远程的服务器对你说: Hello laiheng”。

这是一个简单的能够调用出webservice返回字符串的程序。这是一个入门程序,我刚刚接触的时候就捉摸弄一个webservice的程序,但是没学过.NET,所以挺费劲,初学者要是能够将这个程序调试通过,那就继续跟着我的思路走下去。

在研究soap中出现了一个很严重的问题,如果对方的webservice如果将你的请求返回dataset形式的,我还是建议放弃使用soap形式的调用,去用Axis吧。

        既然写这篇文章的初衷是为了能够让刚刚接触webservice的程序员找到学习的方向,那么先不研究为什么换方法,为什么soap在返回XML的时候为什么会出现序列化与凡序列化的问题。下面进入AXIS的介绍。

 

AXIS

Apache Axis Apache WebService项目中的子项目,其最初起源于IBM"SOAP4J",应该属于最早的一批用于构造基于SOAP应用的Framework 目前Apache Axis已经发展到了第三代,其核心是一个SOAP处理器,用于开发包括客户端,服务器端,SOAP Gateway等各种应用。事实上Apache Axis在了1.0版后,其发行版本还包括了完整的J2EE服务器插件, WSDL支持和生成,TCP/IP监视器等组件,从这个意义上来说Apahce Axis已不仅仅是个SOAP框架了,它包含了除了UDDI外对整个Web Service协议栈(Protocol Stack)的支持。

       AXIS研究的时间不长,在下在到的AXIS包中有一个类叫WSDL2Java,从字面意思就能够理解到这个工具是做什么的。既:提供要调用的webservice描述WSDL,然后生成调用的时候需要的JAVA程序,目前为止我也是只研究到这,因为我们在调用另一个公司提供的webservice的时候对方返回的信息就是dataset,我用soap的方法已经没有办法实现了(后来调查是可以实现的,但是相当麻烦),经商议以后决定修改对方的webservice,将返回的dataset强制tostring,然后再返回到JAVA中作处理。虽然解决了问题,但是改动对方的webservice有损webservice的意义,所以就使用了AXIS。从网上查资料的时候查到了WSDL2JAVA这个类。

对于编写基于AXIS方法能够调用.NETJAVA程序,你必须有一下几个工具:

1、  操作系统

2、  JDK(我使用的是j2sdk1.4.2

3、  axis.jar

commons-discovery.jar

commons-logging.jar

jaxrpc.jar

log4j-1.2.8.jar

name.txt

saaj.jar

wsdl4j.jar

4、  集成开发环境(我的是Eclipse3.1.1

axis包中的jar文件存到jdk下面,在windows控制台中进入jdk目录,然后运行

Java -Djava.ext.dirs=lib org.apache.axis.wsdl.WSDL2Java http://localhost/Add.asmx?wsdl 命令,注意:http://localhost/Add.asmx?wsdl 是你要的文件调用的webservice程序的地址,就是上文说到的那个wsdl文件,如果java环境没有问题的话,wsdl2java就应该将生成的java文件包,存放到jdk主目录下面。你的第一步成功了,生成的文件就能够实现粗略的功能了。

WSDL2Java生成的文件总结如下:

Client-side Bindings

Sample:    java org.apache.axis.wsdl.WSDL2Java AddressBook.wsdl

WSDL 子句

生成的Java

为在type区的每个条目

一个Java

一个Holder类,如果此type被用作inout/out参数

为每个portType

一个Java接口

为每个binding

一个Stub

为每个service

一个service接口

一个service实现(作为定位器)

 

Server-side Bindings

Sample: java org.apache.axis.wsdl.WSDL2Java --server-side AddressBook.wsdl

WSDL 子句

生成的Java

为每个binding

一个Skeleton(—skeletonDeploy设为true)

一个实现模板类(供用户修改为自己的实现)

为所有的services

一个deploy.wsdd文件

一个undeploy.wsdd文件

 

命令参数参考:

Usage:
  
java org.apache.axis.wsdl.WSDL2Java [options] WSDL-URI
Options:

-h, --help

  打印帮助信息后退出

-v, --verbose

  打印报告信息

-n, --noImports

  只生成直接的WSDL代码文档

-O, --timeout <argument>

  超时秒数(默认45, -1表示不限定)

-D, --Debug

  打印调试信息

-W, --noWrapped

  关闭装订(wrapped)文档/文字支持

-s, --server-side

  web service发布服务端绑定

-S, --skeletonDeploy <argument>

  deploy.wsdd中展开纲要(true)或执行(false)
 
默认为false。假定server-side.

-N, --NStoPkg <argument>=<value>

  命名空间到包的映射

-f, --fileNStoPkg <argument>

  命名空间到包的映射文件(默认为NStoPkg.properties)

-p, --package <argument>

  用包名称覆盖所有的命名空间到包的映射

-o, --output <argument>

  发行文件的输出目录

-d, --deployScope <argument>

  增加范围到deploy.xml: Application(应用), Request(请求), Session(会话)

-t, --testCase

  web service发行junit测试用例类

-a, --all

  为所有元素生成代码,包括未引用的元素

-T, --typeMappingVersion

  指示1.11.2. 默认为1.1(SOAP 1.1适用JAX-RPC. 1.2标志SOAP 1.1编码.)

-F, --factory <argument>

  执行GeneratorFactory接口的用户类名称(扩展Java generation函数)

-i, --nsInclude <namespace>

  包含在生成代码中的特定命名范围(默认为所有命名空间,除非用-x选项)

-x, --nsExclude <namespace>

  从生成代码中排除的特定命名空间(默认为none,排除直到第一个用-i选项包含的命名空间)

-p, --property <name>=<value>

  用户GeneratorFactory的属性名称和值

-H, --helperGen

  meta数据发行分离Helper

-U, --user <argument>

  访问WSDL-URI的用户名

-P, --password <argument>

  访问WSDL-URI的密码

-c, --implementationClassName <argument> 用该项作为实现类

假如我要调用的webservice中的laiheng方法,在生成的文件中就有LaihengResponseLaihengResult.Java文件,其中有一块是这样写的:

    public LaihengResponseLaihengResult(

           org.apache.axis.message.MessageElement [] _any) {

           this._any = _any;

}

_any中就有你要的结果了。

写到这里暂时就算写完了吧,其实有好多要写的东西,我这人比较懒,写一篇能够引导新手不走弯路的文章的出发点应该是好的。可是写到这后就没有时间和想法继续写下去了。如果要是看到这篇文章后不明白的地方或者是我写错的地方,请指正。

我的电子邮件是:TTYsonic#gmail.com

 

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页