`
xuyuanshuaaa
  • 浏览: 387772 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

xfire发布webservice服务

 
阅读更多
JavaEE平台从1.3版本开始就完整地支持Web服务,包括调用和发布Web服务两部分。为了让Java应用程序获得访问和发布Web服务的能力,SUN定义了一系列相关的API标准,包括SAAJ、JAXB、JAX-RPC和最新的JAX- WS。

SAAJ(SOAP with Attachments API for Java)已经完整地实现了SOAP协议,可以直接使用SAAJ实现Web服务的底层传输。JAXB(Java Architecture for XML Binding)则实现了XML数据到Java类的绑定,通常我们不直接使用这两个API,而是调用高层的JAX-RPC(Java API for XML-Based RPC)和JAX-WS(Java API for XML-Based Web Services)。JAX-WS是JavaEE最新的Web服务标准,不过仍向下兼容JAX-RPC。
SAAJ(SOAP with Attachments API for Java)
JAXB(Java Architecture for XML Binding)
JAX-RPC(Java API for XML-Based RPC)
JAX-WS(Java API for XML-Based Web Services)
为了在Java中实现Web服务,还必须获得一个具体的实现。Axis和XFire都是实现了完整的Web服务协议的库,可以用于访问和发布 Web服务。
相比其他的Web服务引擎,XFire在实现Web服务上有巨大的配置和性能优势,因此,XFire应当作为JavaEE环境下发布Web服务的首选。
Spring框架的另一个子项目Spring Web Services的目标就是提供一个与Spring紧密结合的Web服务模块,并与Spring的MVC框架集成,这个项目可以作为Spring框架下发布Web服务的又一个选择。不过,Spring Web Services项目目前仍处于开发阶段,尚未有稳定版本发布。现在,Java 6已经正式发布了。Java 6的一个重大特性就是对Web服务的内在支持,发布和访问
Web服务都将变得轻而易举。如果采用Java 6的的Web服务器,那么不必使用任何第三方Web服务的支持库,就可以直接将Web服务完美地集成进来。不过,Java 6从正式发布到各Web服务器对其支持尚需一段较长的时间,目前,在服务器端发布Web服务的最佳选择仍是XFire。
WebService 是 SOA 的一种较好的实现方式,WebService 采用 HTTP 作为传输协议,SOAP(Simple Object Access Protocol)作为传输消息的格式    
XFire一个免费、开源的SOAP框架,它构建了POJO和SOA之间的桥梁,主要特性就是支持将POJO(POJO(Plain Old Java Objects)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。)通过非常简单的方式发布成Web服务,其原理是以接口反射机制自动取得远程方法的
WSDL是一个用来描述Web服务和说明如何与Web服务通信的XML语言

xfire1.2.6支持jdk1.4以上的版本,但是有些比如JSR181注解需要jdk的更高版本,我的例子是一个简单的读取文件程序,服务器是Apache Tomcat6.0.18。
假定你已经了解如何使用Java编写Web应用程序,并知道应该如何把它部署到Apache Tomcat服务器上。话不多说,开始webservice的开发步骤吧!

    1.从xfire的官方网站http://xfire.codehaus.org/Download上下载xfire-distribution-1.2.6.zip最新版的包,压缩包的lib中有它所需的依赖包,将它放入web-info的lib路径下
  2.在web.xml文件中加入
<servlet>
   <servlet-name>XFireServlet</servlet-name>
   <servlet-class>
    org.codehaus.xfire.transport.http.XFireConfigurableServlet
   </servlet-class>
   <load-on-startup>0</load-on-startup>
   </servlet>
   <servlet-mapping>
   <servlet-name>XFireServlet</servlet-name>
   <url-pattern>/services/*</url-pattern>
  </servlet-mapping>

3. 业务代码实现就没有什么好说的啦,如下一个接口(IReadService)和一个实现类(ReadService)
package com.tjn.impl;

public interface IReadService {
  public String readFiles();
}

package com.tjn.impl;

import java.io.File;

public class ReadService implements IReadService {
	//Default constructor.
    public ReadService(){    
    }
	public String readFiles() {
		// TODO Auto-generated method stub
		String result="";
		File file=new File("d:/test");
		String[] files=file.list();
		for (int i = 0; i < files.length; i++) {
			result+=files[i]+"\n";
		}
		return result;
	}
}

默认的构造函数类型必须是public。否则,XFire不能够初始化这个类。
4.services.xml文件中的配置
<beans xmlns="http://xfire.codehaus.org/config/1.0">
	<service>
    <name>WebserviceTest</name>
    <namespace>mywebserviceTest</namespace>
    <serviceClass>com.tjn.impl.IReadService</serviceClass>
    <implementationClass>com.tjn.impl.ReadService</implementationClass>
  	/service>  
	</beans> 
一 name 元素:表示该webService的名称
二 namespace 元素:表示该webService的命名空间
三 serviceClass 元素:表示该webService的接口
四 implementationClass 元素:表示该webService的实现类

services.xml的位置是在meta-inf下新建xfire目录,在里面新建services.xml文件
如果出现错误在将meta-inf整个目录拷贝到web-info下即可


测试服务器端的webservice是否发布成功,测试如下:启动tomcat,在地址栏中输入http://localhost:8080/WebST/services/WebserviceTest?wsdl, 如果能看到类似xml的页面文件就差不多


如果对于一般的接口方法,即方法的返回类型或参数不是List或Map中存放对象的方法,则只需要以上的步骤简单的配置即可。

否则
如果返回类型是List或Map,并且里面存放的是自定义类的话,则需要增加一个对于服务接口的配置文件。该文件的命名规则是 接口文件名.aegis.xml。例如接口是HelloWorld.java的话,则此配置文件命名为HelloWorld.aegis.xml
   1.  <?xml version="1.0" encoding="UTF-8"?>  
   2. <mappings>  
   3.   <mapping >  
   4.     <method name="getUsers">  
   5.       <return-type componentType="com.excellence.webservice.test.User"/>  
   6.     </method>  
   7.   </mapping>  
   8. </mappings>  

该文件和接口要在同一个目录下
getUsers方法返回类型是List,里面装的User对象。对于这种类型的方法,在配置文件中描述了它的返回值类型。
如果返回的类型是Map的话,做法和List一样。但定义的类型,是Map中的Value部分,并且这样的话,Map中Value所存放的对象就必须全部是同一种类

        

一个完整的发布和测试示例:
准备:开发之前请先到官网(http://xfire.codehaus.org/Download)下载xfire-distribution- 1.2.6.zip并解压缩
(1)、新建一个Web项目(服务端),名称为XFireWebService,其目的是为了测试 WebService服务端
为工程添加XFire支持的类库,把xfire-1.2.6里lib所有jar和xfire-all- 1.2.6.jar拷贝到工程lib里
(2)、把XFire加载到系统中来,增加web.xml的配置信息
Java代码 复制代码
<?xml version="1.0" encoding="UTF-8"?>   
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" 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>   
    <servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>   
    <load-on-startup>0</load-on-startup>   
  </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>   
  <welcome-file-list>   
    <welcome-file>index.jsp</welcome-file>   
  </welcome-file-list>   
</web-app>  

(3)、创建Web服务接口,声明该Web服务对外暴露的接口
Java代码 复制代码
package com.test.ws;   
import java.util.List;   
/**  
 * <p>Title: IHelloService</p>  
 * <p>Description: 定义接口</p>  
 */  
public interface IHelloService {       
    public String getTestString(String str);       
    public ExceedVO getTestObject(EnterVO vo);     
    public List getTestList(List list);   
}  

(4)、创建Web服务实现类,为Web服务接口提供实现
Java代码 复制代码
package com.test.ws;  
import java.util.ArrayList;  
import java.util.List;  
/** 
* <p>Title: HelloServiceImpl</p> 
* <p>Description: 接口实现</p> 
*/ 
public class HelloServiceImpl implements IHelloService {   
       
    @Override  
    public String getTestString(String str) {   
        return "Hello" + str;   
    }   
       
    @Override  
    public ExceedVO getTestObject(EnterVO vo) {   
        ExceedVO revo = new ExceedVO();   
        revo.setDescStr(" 名称:"+vo.getName()+"年龄:"+vo.getAge());   
        return revo;   
    }   
       
    @Override  
    public List getTestList(List list) {       
        List<EnterVO> users = new ArrayList<EnterVO>();        
        for(int i=0; i<9; i++){   
            EnterVO user = new EnterVO(" 姓名"+i, i);   
            users.add(user);   
        }   
        return users;   
    }   
}  

5)、这两个类是具体的业务实现类,对业务方法的具体实现放在里面
Java代码 复制代码
package com.test.ws;   
import java.io.Serializable;   
/**  
 * <p>Title: EnterVO</p>  
 * <p>Description: 入参对象</p>  
 */  
public class EnterVO implements Serializable {   
    private static final long serialVersionUID = 1L;       
    private String name;       
        private int age;      
    public String getName() {   
        return name;   
    }      
    public void setName(String name) {   
        this.name = name;   
    }      
    public int getAge() {   
        return age;   
    }      
    public void setAge(int age) {   
        this.age = age;   
    }      
    public EnterVO(String name, int age) {   
        this.name = name;   
        this.age = age;   
    }      
    public EnterVO() { }   
}   
  
package com.test.ws;   
import java.io.Serializable;   
/**  
 * <p>Title: ExceedVO</p>  
 * <p>Description: 出参对象</p>  
 */  
public class ExceedVO implements Serializable {   
    private static final long serialVersionUID = 1L;       
    private String descStr;   
    public String getDescStr() {   
        return descStr;   
    }   
    public void setDescStr(String descStr) {   
        this.descStr = descStr;   
    }   
}  

(6)、在src目录下新建一个META-INF文件夹里包含xfire/service.xml该文件是XFire框架的服务发布文件
Java 代码 复制代码
<?xml version="1.0" encoding="UTF-8"?>  
<!-- 服务发布文件 -->  
<beans xmlns="http://xfire.codehaus.org/config/1.0">  
    <service> <!-- service标签和它所包含的xml内容为发布成Web服务的POJO提供完整的描述 -->  
        <name>HelloService</name> <!-- Web 服务被发布时所采用的唯一名称 -->  
        <namespace>http://test /HelloService</namespace> <!-- Web服务发布时所使用的命名空间 -->  
        <serviceClass>com.test.ws.IHelloService</serviceClass> <!-- Web 服务接口类的全名 -->  
        <implementationClass>com.test.ws.HelloServiceImpl</implementationClass> <!-- Web 服务实现类的全名 -->  
        <!-- 不需要接口时,把业务写在serviceClass标签中 -->  
    </service>  
</beans> 
(7)、注意:当用到List等集合类型时,需要定义Mapping关系
必须与接口同名后缀.aegis.xml,而且要与接口同一位置
Java 代码 复制代码
<mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://xfire.codehaus.org/schemas/1.0/mapping.xsd">  
    <!-- XFire可以支持基本类型,但针对集合类型时需要特殊配置 -->  
    <mapping>  
         <method name="getTestList"> <!-- 需要配置的方法名 --& gt;  
            <!-- index="0"代表方法的参数的序号0即第一个参数,componentType属性代表集合参数内包含的类型 -->  
            <parameter index="0" componentType="java.lang.String" />   
            <!-- 配置返回类型,componentType属性代表返回的集合中所包含的类 -->  
            <return-type componentType="com.test.ws.EnterVO" />   
        </method>          
   </mapping>     
</mappings> 

web.xml和service.xml都可以通过IDE自动生成,也可以手写
(8)、到这步webService服务端就基本完成
部署项目,启动Tomcat,测试一下wsdl,访问http://localhost:8080/XFireWebService/services /HelloService?wsdl
如果能正确显示wsdl文件,说明刚才的部署成功了!!!
(9)、再建一个Web项目(客户端),名称为XFireWebClient,其目的是用来调用一个webService服务
将XFire的库文件拷贝到Web项目的WEB- INF\lib目录下,同时需要将服务器端发布的服务打包发布给客户端,发布给客户端的代码只需要打包接口和参数类即可,实现类不必打包到客户端
这里发布的jar包名称为IHelloService.jar,里面包含IHelloService、EnterVO、ExceedVO这三个类
(10)、在这个Web项目里面新建一个Servlet作为测试的Servlet,名称为ClientTestServlet.java
在web.xml 里面配置好这个Servlet后,就可以在Servlet里面写webService调用的代码了
Java代码
测试过程
package com.test.ws;   
import java.io.IOException;   
import java.net.MalformedURLException;   
import java.util.ArrayList;   
import java.util.List;   
import javax.servlet.ServletException;   
import javax.servlet.http.HttpServlet;   
import javax.servlet.http.HttpServletRequest;   
import javax.servlet.http.HttpServletResponse;   
import org.codehaus.xfire.XFire;   
import org.codehaus.xfire.XFireFactory;   
import org.codehaus.xfire.client.XFireProxyFactory;   
import org.codehaus.xfire.service.Service;   
import org.codehaus.xfire.service.binding.ObjectServiceFactory;   
/**  
 * <p>Title: ClientTestServlet</p>  
 * <p>Description: 测试Servlet</p>  
 */  
public class ClientTestServlet extends HttpServlet {   
  
    private static final long serialVersionUID = 1L;   
  
    public void doGet(HttpServletRequest request, HttpServletResponse response)   
            throws ServletException, IOException {   
           
        request.setCharacterEncoding("UTF-8");     
        Service serviceModel = new ObjectServiceFactory().create(IHelloService.class);          
        XFire xfire = XFireFactory.newInstance().getXFire();   
        XFireProxyFactory factory = new XFireProxyFactory(xfire);        
        String serviceUrl = "http://localhost:8080/XFireWebService/services/HelloService";   
        IHelloService client = null;   
        try {   
            client = (IHelloService) factory.create(serviceModel, serviceUrl);   
        } catch (MalformedURLException e) {   
            e.printStackTrace();   
        }       
           
        String str = client.getTestString("Beijing");   
        request.setAttribute("str", str);   
           
        EnterVO enterVO = new EnterVO();   
        enterVO.setName("Yaodi");   
        enterVO.setAge(26);   
        ExceedVO vo = client.getTestObject(enterVO);   
        request.setAttribute("vo", vo);   
           
        List<String> al = new ArrayList<String>();    
        al.add("111");    
        al.add("222");   
        al.add("333");   
        List list = client.getTestList(al);   
        request.setAttribute("list", list);        
           
        request.getRequestDispatcher("/result.jsp").forward(request, response);   
    }   
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)   
            throws ServletException, IOException {   
        doGet(request,response);   
    }   
       
} 

(11)、注意:XFireWebService项目里的IHelloService.aegis.xml文件,也要放到XFireWebClient项目中来,位置与ClientTestServlet.java同级
(12)、Servlet返回的结果页面:result.jsp
Java 代码 复制代码
<%@ page language="java" pageEncoding="UTF-8"%>  
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>  
<%@ page isELIgnored="false"%>  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
    <title>测试客户端</title>  
  </head>    
  <body>  
    测试客户端!!!<br>  
    String:${str} <br>  
    Object:${vo.descStr} <br>  
    List:<br>  
    <c:forEach items="${list}" var="list">  
        ${list.name} --- ${list.age} <br>  
    </c:forEach>  
  </body>  
</html> 

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page isELIgnored="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>测试客户端</title>
  </head> 
  <body>
    测试客户端!!!<br>
    String:${str} <br>
    Object:${vo.descStr} <br>
    List:<br>
    <c:forEach items="${list}" var="list">
   ${list.name} --- ${list.age} <br>
    </c:forEach>
  </body>
</html>


(13)、同样将这个Web项目发布,同时启动XFireWebService和XFireWebClient这两个应用,然后在地址栏里面输入http://localhost:8080/XFireWebClient/
此时会调用客户端的Servlet,然后调用其 doGet方法,如果正常的话,可以看到页面输出结果了(*^__^*)
问题:在项目中使用XFire发布服务,在本地测试一切正常,但是传到服务器上,发现List的第一个元素是没有内容的,后面的元素内容显示正常,
通过调试服务端没有问题,是往客户端之间传输时丢失的,目前的解决办法比较2,是在List前面加了一条垃圾数据,故意把List的第一个元素挤下来。


有时需要其它语言做服务端,java做客户端,就要用到SOAP获取WebService了
SOAP简单对象访问协议是一种轻量的、简单的、基于 XML 的协议,它被设计成在WEB上交换结构化的和固化的信息


例子是一个可以运行的webservice测试程序,服务端和客户端都是用xFire来实现的。在myeclipse中提及xfire支持就可以了
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics