注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

kangzye的博客

加Q群25382780切磋java,加19360923群研究JavaScript

 
 
 

日志

 
 

Xfire 使用详情  

2011-02-10 16:25:29|  分类: webservice |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
首先,xfire的官网地址是:http://xfire.codehaus.org
xfire 下载地址是:http://xfire.codehaus.org/Download
下载xfire-distribution-1.2.6.zip(http://repository.codehaus.org/org/codehaus/xfire/xfire-distribution/1.2.6/xfire-distribution-1.2.6.zip)其包含xfire-all-1.2.6.jar 以及它依赖的第三方类库(在里面的lib目录中)
       首先搭建服务器端
      使用eclipse,新建一个web项目名为FTService,新建一个interface再新建一个类实现它。当然不建interface直接就一个class类也可以,只是使用interface方式看起来结构漂亮一些。
代码如下:
public interface Test {
    public String fun(String name,int w);
    public int gun(int i);
}
//============
public class TestImpl implements Test{

    @Override
    public String fun(String name,int w) {
        // TODO Auto-generated method stub
        return "hello "+name;
    }

    @Override
    public int gun(int i) {
        // TODO Auto-generated method stub
        return i*2;
    }
}
class G{
    public String name3="3";
    public G(String a,String b){
       
    }
}
这两个类就是我们服务器端做实际事情的类了。
然后就要把这两个类发布成webservice。
        首先我们需要将xfire需要的jar拷贝到项目的lib目录下面去(如果不是对那些所依赖的jar都很清楚,那么将xfire-all-1.2.6.jar和上面提到的lib下面的所有jar都拷贝过去),然后就是需要建立一个服务的描述文件,默认情况下这个文件是在类环境下能找到的META-INF/xfire/services.xml ,开始的时候我发现新建的web项目下面就有个META-INFO目录,于是我就在其下建立了xfire/service.xml。结果是报错说找不到 META-INF/xfire/services.xml ,后来发现是web项目默认的 META-INF 目录不是处于类查找环境目录下,于是我将其移动到其兄弟目录WEB-INF中去就不报错了。
        services.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xfire.codehaus.org/config/1.0">
    <service>
        <name>testW</name>
        <namespace>http://www.kangzye.com/t1</namespace>
        <serviceClass>com.fractalist.ws.test.Test</serviceClass>
        <implementationClass>com.fractalist.ws.test.TestImpl</implementationClass>
    </service>
    <service>
        <name>test2</name>
        <namespace>http://www.kangzye.com/t2</namespace>
        <serviceClass>com.fractalist.ws.test.Test2</serviceClass>
    </service>

</beans>

红色部分是一个没有用interface的例子,在此可删除去。保存此文件然后就是在web.xml中为xfire添加servlet 就ok了。
        打开web.xml加入以下代码:
<servlet>
      <servlet-name>XFireServlet2</servlet-name>
      <servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>XFireServlet2</servlet-name>
      <url-pattern>/servlet/xfireServlet/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
      <servlet-name>XFireServlet2</servlet-name>
      <url-pattern>/services/*</url-pattern>
  </servlet-mapping>

做完以上步骤服务器端就做好了,启动服务器后即可在浏览器中输入http://localhost/FTService/services 即可浏览此webservice下发布的服务了
Xfire 使用笔记 - kangzye - kangzye的博客
==========================================================================
然后就是客户端如何消费这些服务的问题了
客户端调用服务器端的服务有多种方式,这里介绍其中几种。
       1、生成客户端代码方式,然后直接调用客户端类的方式
         生成客户端代码需要先能得到上面发布出来的wsdl文件,得到wsdl文件后,生成客户端代码的方式是有多种,可以用IDE(如eclipse)生成,我这里使用ant 来生成,新建一个客户端项目(java项目即可),建立一个lib目录,将xfire依赖的jar都拷贝到其中。然后将它们引入到项目中供项目使用。
        然后新建一个xml文件,这里叫 build.xml,代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<project name="facet" default="help" basedir=".">
    <!-- 设置属性 -->
    <property name="optimize" value="false" />
    <property name="debug" value="on" />
    <property name="deprecation" value="false" />
    <property name="build.lib" value="${basedir}/lib" />
    <property name="sources" value="${basedir}/src" />
    <property name="build.classes" value="${basedir}/bin" />
    <!-- 设置类路径-->
    <path id="classpath">
        <pathelement location="${build.classes}" />
        <fileset dir="${build.lib}">
            <include name="*.jar" />
        </fileset>
    </path>
    <taskdef name="wsgen" classname="org.codehaus.xfire.gen.WsGenTask" classpathref="http://kangzye.blog.163.com/blog/classpath" />
    <!-- 帮助   -->
    <target name="help" description="显示帮助信息">
        <echo message="target                 描述" />
        <echo message="-----------------------------------------------------------------" />
        <echo message="compile                编译 " />
        <echo message="create_code           创建代码" />
    </target>
    <!-- 编译代码 -->
    <target name="compile" description="编译代码">
        <echo>编译程序代码</echo>
        <javac srcdir="${sources}" destdir="${build.classes}"
            classpathref="http://kangzye.blog.163.com/blog/classpath" debug="${debug}" optimize="${optimize}"
            deprecation="${deprecation}" />
    </target>
    <!-- 创建客户端代码   -->
    <target name="create_code" description="创建代码">
        <echo>创建代码</echo>
        <wsgen outputDirectory="${sources}" wsdl="${basedir}/wsdl/testW.wsdl"
            package="com.fractalist.ws.client.test" overwrite="true" />
    </target>

</project>

上面的代码可做适当修改来符合个人要求,我们运行上面绿色的代码即可生产客户端代码。但在运行之前还有一个步骤要做,就是需要将wsdl文件下载下来保存到项目的wsdl目录下,如上面蓝色部分代码。生成的客户端代码结构如下:
Xfire 使用笔记 - kangzye - kangzye的博客
我们需要直接调用的类就是 testWClient.java 和 testWPortType.java:
//===============
package customer;

import com.fractalist.ws.client.test.testWClient;
import com.fractalist.ws.client.test.testWPortType;

public class Main {
    public static void main(String[] args){
        long l=System.currentTimeMillis();
        testWClient wc=new testWClient();
        testWPortType wt=wc.gettestWHttpPort();
        String ss=wt.fun("kangzzz", 3);
        System.out.println(ss);
        System.out.println("use "+(System.currentTimeMillis()-l)/1000+"s");
    }
}

//===========输出==========
hello kangzzz
use 3s
//=========================

2、直接调用client方式
代码如下:
public class DynamicClient
{
    public static void main(String[] args) throws MalformedURLException, Exception
    {
        Client client = new Client(new URL("http://localhost:8080/facet/servlet/XFireServlet/HelloService?wsdl"));
        Object[] results = client.invoke("hello", new Object[] {"Juliet"});
        System.out.println((String) results[0]);
    }
}
其中 hello 就是要调用的方法的方法名,new Object[] {"Juliet"} 就是 hello方法要用到的参数。这样的调用很简单,但使用时需要转型,比较麻烦。

下面想讲讲xfire生成的客户端。
webservice 的服务差不多可以理解为服务器端的一个类中的一个方法,需要发布这个类为服务,则需要将此类声明道xfire 指定的文件:META-INF/xfire/services.xml 中。被发布的类所有的public方法(无论方法名是getter或者setter 或者任意形式)将会在生成的客户端中体现出来(客户端可以调用这些方法),而属性默认是不会被体现出来的。
        然后就是如果被发布的服务器端方法返回的类型不是基本类型(如String、int、boolean等等),而是自定义类型,比 如:com.kangzye.ws.test.pojo.User ,会怎么样呢?如果你用的jdk是1.4以及以下版本,则需要为被发布的类在该类的相同位置编写一个 <class-name>.agis.xml 。比如你发布了一个类:
public class Myws{
   public User findAUser(){...}
   public String loadName(){...}
}
那么需要在Myws.java相同位置编写一个文件名为: Myws.agis.xml
<mappings>
   <mapping>
      <method name="findAUser">
         <return-type componentType="com.kangzye.ws.test.pojo.User" />
      </method>
   </mapping>
</mappings>
由于loadName方法返回的是基本类型,则不需要做声明,另外如果方法中参数是自定义类型,那么则这么做:
比如如果 Myws.java 中又有个方法:
public String findUser(String name,User user){...}
那么Myws.agis.xml 需要在<mapping> 中加入:
<method name="findUser">
    <parameter index="1" componentType="com.kangzye.ws.test.pojo.User" />
</method>
index表示声明的是第二个参数(从0开始),由于第一个是基本类型,则可省略声明。
到此,User会出现在客户端中(这叫做映射POJO),那其是否需要加一个 aegis绑定呢?答案是如果User中的所有getter方法中如果参数以及返回类型都是基本类型,则不需要,否则就需要。
下面贴出一句在网络是拷贝N百遍的话:
当使用JDK1.4时,或者对JDK1.5的范型和注释不是很熟悉的情况下,当遇到需要映射POJO或配置WebService接口方法返回类型(如集合类型)时,需要进行绑定,此时aegis的绑定为建立.aegis.xml的文件
问题:
1、对上面绿色的话不是很理解,貌似不需要做任何映射上的手脚,什么都不做,也是没有问题的。
2、当服务器端返回类型是Set<XX>时,在生成的客户端上却变成了 List<XX>。
以上问题请高手赐教

  评论这张
 
阅读(1300)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017