XFire——WebService XFire实现

一、XFire——WebService实现

1.>  下载jar包和文档

ª       先从官网(http://xfire.codehaus.org/)下载需要的jar包和文档

ª       编写CalculatorService接口

ª       

ª       WebService一般都是由两部分来组成的,一般有一个接口,接口用是来公开服务的,服务的执行由接口的实现类,来实现的。

2.>  新建(java Web)项目

ª       新建(java Web)项目――myxfire实现简单的加、减、乘、除接口

XFire——WebService XFire实现_第1张图片

ª       编写CalculatorService接口

package com.test.service;

publicinterfaceCalculatorService {

   /**

    *

    *@parama加数

    *@paramb 加数

    *@return  

    */

   publicint add(int a, int b);

   /**

    *

    *@parama 被减数

    *@paramb  减数

    *@return   

    */

   publicint subtract(int a, int b);

   /**

    *

    *@parama 因数

    *@paramb 因数

    *@return  

    */

   publicint multiply(int a, int b);

   /**

    *

    *@parama 被除数

    *@paramb  除数

    *@return   

    */

   publicint divide(int a, int b);

}

ª       编写web.xml文件,在web.xml文件中加入XFireServlet类的<servlet-mapping>,可以从下载的文档中实例中获得web.xml文件内容。

<?xmlversion="1.0"encoding="UTF-8"?>

<web-appversion="2.5"

xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

 

<servlet>

<servlet-name>XFireServlet</servlet-name>

<display-name>XFire Servlet</display-name>

<servlet-class>

org.codehaus.xfire.transport.http.XFireConfigurableServlet

</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>XFireServlet</servlet-name>

<url-pattern>/servlet/XFireServlet/*</url-pattern>

</servlet-mapping>

 

<servlet-mapping>

<servlet-name>XFireServlet</servlet-name>

<url-pattern>/services/*</url-pattern>

</servlet-mapping>

</web-app>

 

ª       在目录下新建META-INF文件夹,META-INF目录下新建services.xml文件,并编写services.xml

                        i.             编写services.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://xfire.codehaus.org/config/1.0">

<service>

<!--指定服务的名称 -->

<name>CalculatorService</name>

<!--指定服务的接口 -->

<serviceClass>com.test.service.CalculatorService</serviceClass>

<!--指定接口的实现类 -->

<implementationClass>

   com.test.service.impl.CalculatorServiceImpl

</implementationClass>

</service>

</beans>

ª       当服务器启动的时候,会加载web.xml中的配置信息,读取XfireConfigurableServlet,然后会将CalculatorService以服务(wsdl)的形式发布出去。

 

3.> Xfire-添加所需要的jar

ª       添加所需要的jar,添加lib上当下所有的jar,和xfire-all-1.2.6.jar,其中lib目录下的jar包是所依赖的jar

ª       

ª       wsdl全称为:Web Service Description LanguagewsdlXML,公开服务越多,wsdl就越多。

ª       部署项目运行,以下图为例运行项目。

ª       XFire——WebService XFire实现_第2张图片

ª       根据web.xml文件中的配置,打开IE浏览器,在地址输入,http://localhost:8080/myxfire/services,显示:

ª       XFire——WebService XFire实现_第3张图片

4.> 分析WSDL内容

           ª       点击[wsdl]后会显示所对应的Schema信息,如下图所示:

<?xmlversion="1.0" encoding="UTF-8" ?>

-<wsdl:definitions targetNamespace="http://service.test.com" xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding" xmlns:tns="http://service.test.com" xmlns:wsdl=http://schemas.xmlsoap.org/wsdl/"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/"xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/"xmlns:soap12="http://www.w3.org/2003/05/soap-envelope>

-<wsdl:types>

 

-<xsd:schemaxmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified"   targetNamespace="http://service.test.com">

 

-<xsd:element name="subtract">

-<xsd:complexType>

-<xsd:sequence>

 <xsd:elementmaxOccurs="1" minOccurs="1" name="in0" type="xsd:int" />

 <xsd:elementmaxOccurs="1" minOccurs="1" name="in1" type="xsd:int" />

 </xsd:sequence>

 </xsd:complexType>

</xsd:element>

 

-<xsd:element name="subtractResponse">

-<xsd:complexType>

-<xsd:sequence>

 <xsd:elementmaxOccurs="1" minOccurs="1" name="out" type="xsd:int" />

 </xsd:sequence>

 </xsd:complexType>

 </xsd:element>

 

-<xsd:element name="multiply">

-<xsd:complexType>

-<xsd:sequence>

 <xsd:elementmaxOccurs="1" minOccurs="1" name="in0" type="xsd:int" />

 <xsd:elementmaxOccurs="1" minOccurs="1" name="in1" type="xsd:int" />

 </xsd:sequence>

 </xsd:complexType>

 </xsd:element>

 

-<xsd:element name="multiplyResponse">

-<xsd:complexType>

-<xsd:sequence>

 <xsd:elementmaxOccurs="1" minOccurs="1" name="out" type="xsd:int" />

 </xsd:sequence>

 </xsd:complexType>

 </xsd:element>

 

-<xsd:element name="divide">

-<xsd:complexType>

-<xsd:sequence>

 <xsd:elementmaxOccurs="1" minOccurs="1" name="in0" type="xsd:int" />

 <xsd:elementmaxOccurs="1" minOccurs="1" name="in1" type="xsd:int" />

 </xsd:sequence>

 </xsd:complexType>

 </xsd:element>

 

-<xsd:element name="divideResponse">

-<xsd:complexType>

-<xsd:sequence>

 <xsd:elementmaxOccurs="1" minOccurs="1" name="out" type="xsd:int" />

 </xsd:sequence>

 </xsd:complexType>

 </xsd:element>

 

-<xsd:element name="add">

-<xsd:complexType>

-<xsd:sequence>

 <xsd:elementmaxOccurs="1" minOccurs="1" name="in0" type="xsd:int" />

 <xsd:elementmaxOccurs="1" minOccurs="1" name="in1" type="xsd:int" />

 </xsd:sequence>

 </xsd:complexType>

 </xsd:element>

 

-<xsd:element name="addResponse">

-<xsd:complexType>

-<xsd:sequence>

 <xsd:elementmaxOccurs="1" minOccurs="1" name="out" type="xsd:int" />

 </xsd:sequence>

 </xsd:complexType>

 </xsd:element>

 </xsd:schema>

 </wsdl:types>

 

-<wsdl:message name="divideRequest">

 <wsdl:partname="parameters" element="tns:divide" />

 </wsdl:message>

-<wsdl:message name="multiplyResponse">

 <wsdl:partname="parameters" element="tns:multiplyResponse" />

 </wsdl:message>

 

-<wsdl:message name="multiplyRequest">

 <wsdl:partname="parameters" element="tns:multiply" />

 </wsdl:message>

-<wsdl:message name="addResponse">

 <wsdl:partname="parameters" element="tns:addResponse" />

 </wsdl:message>

-<wsdl:message name="subtractRequest">

 <wsdl:partname="parameters" element="tns:subtract" />

 </wsdl:message>

-<wsdl:message name="divideResponse">

 <wsdl:partname="parameters" element="tns:divideResponse" />

 </wsdl:message>

-<wsdl:message name="subtractResponse">

 <wsdl:partname="parameters" element="tns:subtractResponse" />

 </wsdl:message>

-<wsdl:message name="addRequest">

 <wsdl:partname="parameters" element="tns:add" />

 </wsdl:message>

 

-<wsdl:portType name="CalculatorServicePortType">

-<wsdl:operation name="subtract">

 <wsdl:inputname="subtractRequest" message="tns:subtractRequest" />

 <wsdl:outputname="subtractResponse" message="tns:subtractResponse" />

 </wsdl:operation>

 

-<wsdl:operation name="multiply">

 <wsdl:inputname="multiplyRequest" message="tns:multiplyRequest" />

 <wsdl:outputname="multiplyResponse" message="tns:multiplyResponse" />

 </wsdl:operation>

 

-<wsdl:operation name="divide">

 <wsdl:inputname="divideRequest" message="tns:divideRequest" />

 <wsdl:outputname="divideResponse" message="tns:divideResponse" />

 </wsdl:operation>

 

-<wsdl:operation name="add">

 <wsdl:inputname="addRequest" message="tns:addRequest" />

 <wsdl:outputname="addResponse" message="tns:addResponse" />

 </wsdl:operation>

 </wsdl:portType>

 

-<wsdl:binding name="CalculatorServiceHttpBinding" type="tns:CalculatorServicePortType">

 <wsdlsoap:bindingstyle="document" transport="http://schemas.xmlsoap.org/soap/http" />

-<wsdl:operation name="subtract">

 <wsdlsoap:operationsoapAction="" />

-<wsdl:input name="subtractRequest">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:input>

-<wsdl:output name="subtractResponse">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:output>

 </wsdl:operation>

-<wsdl:operation name="multiply">

 <wsdlsoap:operationsoapAction="" />

-<wsdl:input name="multiplyRequest">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:input>

-<wsdl:output name="multiplyResponse">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:output>

 </wsdl:operation>

-<wsdl:operation name="divide">

 <wsdlsoap:operationsoapAction="" />

-<wsdl:input name="divideRequest">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:input>

-<wsdl:output name="divideResponse">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:output>

 </wsdl:operation>

-<wsdl:operation name="add">

 <wsdlsoap:operationsoapAction="" />

-<wsdl:input name="addRequest">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:input>

-<wsdl:output name="addResponse">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:output>

 </wsdl:operation>

 </wsdl:binding>

-<wsdl:service name="CalculatorService">

-<wsdl:port name="CalculatorServiceHttpPort" binding="tns:CalculatorServiceHttpBinding">

 <wsdlsoap:addresslocation="http://localhost:8080/myxfire/services/CalculatorService" />

 </wsdl:port>

 </wsdl:service>

 </wsdl:definitions>

 

                        i.             头部的网站都是固定的,除xmlns:tns="http://service.test.com"是根据包名反转生成的。

                      ii.             <wsdl:message name="divideRequest">消息,服务器端收到消息后,进行处理,向客户端返回一个消息,请求结束。一共4个方法,8个消息。

                     iii.             service最重要的是:

<wsdlsoap:address lcation="http://localhost:8080/myxfire/services/CalculatorService"/>指定了服务的地址。

                     iv.             对于元素来说都是严格,上面的依然下面的,例如:

1.        请求:

-<xsd:element name="subtract">

-<xsd:complexType>

-<xsd:sequence>

 <xsd:elementmaxOccurs="1" minOccurs="1" name="in0" type="xsd:int" />

 <xsd:elementmaxOccurs="1" minOccurs="1" name="in1" type="xsd:int" />

 </xsd:sequence>

 </xsd:complexType>

</xsd:element>

定义了两个元素,类型为int类型,最多出显1次,最少出现1次。

 

2.        响应: 

-<xsd:element name="subtractResponse">

-<xsd:complexType>

-<xsd:sequence>

 <xsd:elementmaxOccurs="1" minOccurs="1" name="out" type="xsd:int" />

 </xsd:sequence>

 </xsd:complexType>

 </xsd:element>

定义了一个元素,类型为int类型,最多出显1次,最少出现1  

 

ª       从上面的例子中可以看出,将方法的参数做了一复杂类型,将方法的返回值做了一个复杂类型:

<wsdl:message name="subtractRequest">

      l:partname="parameters" element="tns:subtract" />

 </wsdl:message>

                        i.             当从服务器端发出请求,符合tns:subtract元素的xml对象,处理请求完之后,会向客户端返回一个符合subtractResponse元素的xml对象

-<xsd:element name="subtractResponse">

-<xsd:complexType>

-<xsd:sequence>

 <xsd:elementmaxOccurs="1"minOccurs="1" name="out" type="xsd:int"/>

 </xsd:sequence>

 </xsd:complexType>

 </xsd:element>

ª       portType定义了具体的方法,每一个operation代表了一个方法。调用方法时,会输入一个消息,当方法回来时候又返回来一个消息。每一个operation里面,有两个元素:inputoutputinput表示调用方法时候,传递一个tns:subtractRequest消息,output表示调用方法时候,传回一个tns:subtractResponse消息。

-<wsdl:portType name="CalculatorServicePortType">

-<wsdl:operation name="subtract">

 <wsdl:inputname="subtractRequest" message="tns:subtractRequest" />

 <wsdl:outputname="subtractResponse" message="tns:subtractResponse" />

 </wsdl:operation>

 

-<wsdl:operation name="multiply">

 <wsdl:inputname="multiplyRequest" message="tns:multiplyRequest" />

 <wsdl:outputname="multiplyResponse" message="tns:multiplyResponse" />

 </wsdl:operation>

 

-<wsdl:operation name="divide">

 <wsdl:inputname="divideRequest" message="tns:divideRequest" />

 <wsdl:outputname="divideResponse" message="tns:divideResponse" />

 </wsdl:operation>

 

-<wsdl:operation name="add">

 <wsdl:inputname="addRequest" message="tns:addRequest" />

 <wsdl:outputname="addResponse" message="tns:addResponse" />

 </wsdl:operation>

 </wsdl:portType>

 

ª       依赖:

-<wsdl:binding name="CalculatorServiceHttpBinding" type="tns:CalculatorServicePortType">

 <wsdlsoap:bindingstyle="document" transport="http://schemas.xmlsoap.org/soap/http" />

-<wsdl:operation name="subtract">

 <wsdlsoap:operationsoapAction="" />

-<wsdl:input name="subtractRequest">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:input>

-<wsdl:output name="subtractResponse">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:output>

 </wsdl:operation>

-<wsdl:operation name="multiply">

 <wsdlsoap:operationsoapAction="" />

-<wsdl:input name="multiplyRequest">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:input>

-<wsdl:output name="multiplyResponse">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:output>

 </wsdl:operation>

-<wsdl:operation name="divide">

 <wsdlsoap:operationsoapAction="" />

-<wsdl:input name="divideRequest">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:input>

-<wsdl:output name="divideResponse">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:output>

 </wsdl:operation>

-<wsdl:operation name="add">

 <wsdlsoap:operationsoapAction="" />

-<wsdl:input name="addRequest">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:input>

-<wsdl:output name="addResponse">

 <wsdlsoap:bodyuse="literal" />

 </wsdl:output>

 </wsdl:operation>

 </wsdl:binding>

-<wsdl:service name="CalculatorService">

-<wsdl:port name="CalculatorServiceHttpPort" binding="tns:CalculatorServiceHttpBinding">

 <wsdlsoap:addresslocation="http://localhost:8080/myxfire/services/CalculatorService" />

 </wsdl:port>

 </wsdl:service>

 </wsdl:definitions>

Service使用BindingBinding使用ProtType, ProtType使用message, message使用自己定义的type

 

5.>  新建(java Web)项目

 ª       新建(java)项目――xfire_clinet实现简单的加、减、乘、除接口调用

ª       Xfire提供了Ant(自动构建)实现在客户端实现在远程调用,先从官网(http://xfire.codehaus.org/Download

                        i.             Client and Server StubGeneration from WSDL:从wsdl里面产生服务端与客户端的Stub

                      ii.             Stub:所谓的Stub,像一个代理,由本地的代理远程的一个接口。

     

                     iii.              Xfire官方提供的示例:<taskdef>定义一个任务,<wsgen>使用任务。

ª       在项目实现自动构建(Ant

                        i.             在项目根路径下新建build.properties

#生成的目录 basedir引用的build.xml中的basedir

src.dir=${basedir}/src

#源代码的目录

lib.dir=E:/Work/xfire-1.2.6/lib/

#指定wsdl的路径

wsdl.dir=http://localhost:8080/myxfire/services/CalculatorService?wsdl

                      ii.             在项目根路径下新建build.xml

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

<!--定义project的名称, basedir定义为当前目录-->

<projectname="WebService"basedir="."default="gen-webservice">

       <!--导入properties文件导入 -->

       <propertyfile="build.properties"></property>

       <!--指定jar包所在的位置-->

   <pathid="project-classpath">

       <!--fileset指文件包文件 lib.dir是在properties中定义的-->

       <filesetdir="${lib.dir}">

           <!--包含所有的以.jar文件-->

           <includename="**/*.jar"/>

       </fileset>

   </path>

   

     <targetname="gen-webservice">

<taskedname="wsgen"classname="org.codehaus.xfire.gen.WsGenTask"classpathref="project-classpath"/>

<wsgenoutputDirectory="${src.dir}"wsdl="${wsdl.dir}"package="com.xfire.client"overwrite="true"/>

     </target>

</project>

                     iii.             运行后的效果如图:

                   XFire——WebService XFire实现_第4张图片

ª       分析客户端代码

                        i.             com.xfire.client.CalculatorServiceClient.java文件

                      ii.             XFire——WebService XFire实现_第5张图片

                     iii.             图中画红线的地址为:访问远程服务器的地址,类中其它代码暂时先不去考虑。

                     iv.             打开CalculatorServicePortType接口,可以看到定义的方法,可以看作远程服务器的方法在客户的上面的Stub,客户端尝试接口里面的方法,就可以了,在底层会将调口访问的过程发送给服务端,由服务端进行处理。

ª       写测试类进行测试

                        i.             代码:

   publicstaticvoid main(String[] args) {     

      //构造方法会完成本地Stub创建,以及服务器之间的链接

      CalculatorServiceClient client =new CalculatorServiceClient();

      // CalculatorService代理对象

CalculatorServicePortType portType = client.

getCalculatorServiceHttpPort();

      intaddResult = portType.add(1, 2);

      System.out.println("addResult===>" + addResult);

}

输出结果:addResult===>3

  6.>  使用JMeter测试Web Service TcpMon使用详解

ª       TCPMon使用及原理

                        i.             WebService服务器和客户机之间会传递SOAP消息,有时我们需要得到这些消息以便调试,而ApacheTCPMon可以帮助我们做到这一点

                      ii.             TCPMon的下载地址在http://download.csdn.net/detail/yuan_xw/4444457,双击tcpmon.jar就可以执行程序了。

                     iii.             这里有必要对tcpmon说明一下,它实际上是个代理,起一个消息转发的作用,监视的是转发出去的消息。最终,消息还是要送到具体的地址和端口,否则响应就不正确了。也就是说,TCPMon是一个消息的二传手,它的前后都应该配置正确才行。

                     iv.             请求原理示意图:

                         XFire——WebService XFire实现_第6张图片

 

            v.             双击tcpmon.jar启动后,

1. LocalPort:本地端口

2.        Service Name:服务器的名字

3.        SSL Service:服务端的端口

                     vi.             配置如图所示:

 

                   vii.             需要将刚才CalculatorServiceClient类中的构造方法中http://localhost:8080/myxfire/services/CalculatorService

修改URL地址端号为8080http://localhost:5555/myxfire/services/CalculatorService

                  XFire——WebService XFire实现_第7张图片

                  

                 viii.             当我们再次运行程序时,请求的xml就出现

                     ix.             对于soap消息来说有两种,       

1.        Envelope信封

2.        真正的主要内容是在<soap:Body></soap:Body>之间

                      x.             上半部分是客户端请求,下半部分是服务器应响。

 

ª       Web Service的压力测试,压力测试工具——JMeter

                        i.             JMeter下载地址:http://jmeter.apache.org/download_jmeter.cgi

                      ii.             先执行jmeter.bat,再运行ApacheJMeter.jar

ª       ApacheJMeter操作

                        i.             第一步:修改测试计划的名称:testplan   

               

                      ii.             第二步:添加线程组,一个线程代表者一个用户

       XFire——WebService XFire实现_第8张图片

                     iii.             第三步:线程组参数配置

1.        线程数:10            表示:模拟10个用户

2.        循环次数:    

a)        永远:不停的地访问

b)        指定具体如数字:10 每个线程执行10      

3.        Ramp-Up Period(in seconds):间隔时间:

a)        10    表示,第一个线程和第二线程之间的间隔几秒钟,间隔总时间。

 

                     iv.             第四步:设置Sampler(采样器)

1.        添加Sampler

XFire——WebService XFire实现_第9张图片

                      v.             第五步:设置SOAP/XML-RPCRequest参数

1.        XFire——WebService XFire实现_第10张图片

a)        URL:表示远程webService的服务器地址

b)        Soap/XML-RPC Data:表示每次请求访问的数据(数据从TCPMon中复XML请求数据即可)。

c)        文件名:将执行的结果返回到一个文件里面

ª       修改服务器端代码,添加显示报表,测试运行

打开com.test.service.impl.CalculatorServiceImpl类,请求的Soap/XML-RPC Data中请求的是服务器端的服务方法,修改服务器端的add方法,测试是否被调用。   

                        i.             代码所示:

publicclassCalculatorServiceImplimplements CalculatorService {

           privateintindex = 0;

   publicint add(int a, int b) {

       ++index;

       System.out.println("add invoked:" +index);

       return a + b;

}

忽略剩余代码……

                      ii.             添加显示报表,如下图:

            

依次添加图形结果、用表格查看结果、查看结果树。

                     iii.             先保存,点击菜单栏上的“启动”,可以在服务器端的控制台,看到调用执行的结果,如图:

1.        Tomcat执行结果:

XFire——WebService XFire实现_第11张图片

根据参数设置add方法会被执行100次。

2.        ApacheJMeter执行结果图:

   

图标如果是绿色的表示请求是成功的。

3.        Web Service需要注意:

a)        WebService里面,一种方法经常会有多个操作,与传统在项目用直接调用方法不同,是一种粗粒度的,远程调用服务器一个方法,方法尽量把客户在一次请求所要做的业务处理全部完成,而不希望客户端完成一次业务处理,去掉N次。

b)        WebService会存在性能的问题。

c)        在项目开发里面,使用ApacheJMeter比较常用,有时间可以研究。

 

 

 

          学习WebService推荐的书籍:

             《Web_Service开发指南_2_1_.4

                                                                                                                                                                                                                                                ——厚积薄发(yuanxw

 

 

你可能感兴趣的:(webservice,service,服务器,Parameters,binding,output)