CXF开发与配置webservice .

来源:互联网 发布:.date域名过期 编辑:程序博客网 时间:2024/04/27 20:16

转自:http://blog.csdn.net/cyf_cyf/article/details/7187911

 

Apache CXF 继承自Celtix 和XFire这两大开源项目,Apache CXF 的前身叫 Apache CeltiXfire,现在已经正式更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。
       Apache CXF 是一个开源的 Services 框架,CXF 帮助您利用 Frontend 编程 API 来构建和开发 Services ,像 JAX-WS 。这些 Services 可以支持多种协议,比如:SOAP、XML/HTTP、RESTful HTTP 或者 CORBA ,并且可以在多种传输协议上运行,比如:HTTP、JMS 或者 JBI,CXF 大大简化了 Services 的创建,同时它继承了 XFire 传统,一样可以天然地和 Spring 进行无缝集成。
下面来说一下cxf的简单配置:
1 web.xml中对cxf的配置如下
<!-- 监听的配置 -->
<listener>
<!-- spring监听的配置 -->
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- servlet的配置 -->
<servlet>
<!-- cxf的servlet名 -->
<servlet-name>CXFServlet</servlet-name>
<!-- cxf的servlet类 -->
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<!-- cxf的servlet名 -->
<servlet-name>CXFServlet</servlet-name>
<!-- 触发cxf的servlet的 -->
<url-pattern>/*</url-pattern>
</servlet-mapping>

2 服务端spring的配置文件
其中import部分的内容就是cxf包中的相关配置文件,
aegisBean为用aegis方式来绑定数据,这个在下边的jaxws的工厂类中需要指定一下,应为默认是使用JAXB方式绑定数据。
jaxWsServiceFactoryBean是作为暴露出的端点(endpoint)TsbWebService的工厂类。端点TsbWebService的implementor属性用于
指定真正暴露出的服务的实现类,而address属性表示该服务生成的wsdl文件的地址。如果要将不同的wsdl部署在同一个url上,
则需要将不同的端点使用不同的工厂类实例。
(如下边的例子访问地址为http://localhost:8080/项目所在目录/Tsb?wsdl)
在端点的inInterceptors部分中红字的部分是用于验证soap协议中自定义head部分验证信息所使用,这一部分下篇文章再说。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws 
http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

<bean id="aegisBean" class="org.apache.cxf.aegis.databinding.AegisDatabinding" />

<bean id="jaxWsServiceFactoryBean" class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
<property name="wrapped" value="true" />
<property name="dataBinding" ref="aegisBean" />
</bean>

    <bean id="cyfWsServiceFactoryBean" class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
<property name="wrapped" value="true" />
<property name="dataBinding" ref="aegisBean" />
    </bean>

    <jaxws:endpoint id="cyfTest" implementor="tsb.ws.tsbimpl.CyfImpl" address="/Cyf">
       <!--  <jaxws:inInterceptors>
日志拦截器
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxws:inInterceptors> -->
<jaxws:serviceFactory>
<ref bean="cyfWsServiceFactoryBean" />
</jaxws:serviceFactory>
<!-- <jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" />
</jaxws:features>  -->   
    </jaxws:endpoint>

<!-- 暴露出的服务 -->
<jaxws:endpoint id="TsbWebService1" implementor="tsb.ws.tsbimpl.TsbWebServiceImpl" address="/Tsb">
<jaxws:inInterceptors>
<!-- 日志拦截器 -->
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<!-- 自定义拦截器,用于实现认证操作 -->
<bean class="tsb.ws.common.authentication.ReadSoapHeader" />
</jaxws:inInterceptors>
<jaxws:serviceFactory>
<ref bean="jaxWsServiceFactoryBean" />
</jaxws:serviceFactory>
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" />
</jaxws:features>
</jaxws:endpoint>
</beans>

3 服务端实现类的接口
上文所示的端点cyfTest的实现类CyfImpl还需要继承一个接口,这个接口为ICyf,这里我们采用codefirst的方式定义服务。
package tsb.ws.tsbinterface;


import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;


@WebService(targetNamespace = "http://apache.org/")
public interface ICyf {

@WebMethod
public String HelloCYF(@WebParam(name = "strParams", targetNamespace = "http://apache.org/") String strParams); 


}
注解@WebService 就标注了这个接口的方法将公开为Web 服务,使用了这个注解的接口的所有方法都将公开为Web 服务的操作。
我们也通常把公开为Web服务的接口叫做SEI(Service EndPoint Interface)服务端点接口
其中@WebMethod注解和@WebParam注解分别用于指定方法与方法的参数,这两项都是可选项。@WebParam如果未指定name属性的话则在
客户端调用时显示的参数为arg0、arg1...以此类推。制作好接口之后实现类CyfImpl就可以继承这个接口并实现接口中定义的服务。
*****************************************************************************************************************************************************************
4 客户端的spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

<bean id="cyfServiceFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="address"
value="http://localhost:8080/TsbWebService/Cyf?wsdl"></property>
<property name="serviceClass" value="tsb.ws.tsbinterface.ICyfClient"></property>
<property name="outInterceptors">
<list>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<!--用于添加自定义头部验证信息 <bean class="tsb.ws.common.authentication.AddPptSoapHeader"></bean> -->
</list>
</property>
</bean>
</beans>


       其中cyfServiceFactory为客户端的服务代理bean,它的地址由属性address指定,
另外我们还需要制作一个客户端服务接口以和服务端的接口内容一一对应,这里我们指定该接口为ICyfClient,
最后outInterceptors中指定的AddPptSoapHeader用于head信息验证,还是在下篇文章中再讲。


5 客户端接口
package tsb.ws.tsbinterface;
import javax.jws.WebParam;
import javax.jws.WebService;


@WebService(targetNamespace="http://apache.org/")
public interface ICyfClient {


public String Cnm(String strParams);

}
       该接口用于定义和服务端端点中的方法一一对应,不使用的方法可以不写。
客户端实现类只要在用到的地方
ICyfClient cyfClient = (ICyfClient)cyfServiceFactory.create();
cyfClient.cnm();
       当然如果不在spring中配置服务代理也是可以在程序中直接写调用的
JaxWsProxyFactoryBean proxyFb = new JaxWsProxyFactoryBean();
proxyFb.setAddress("http://localhost:8080/TsbWebService/Cyf?wsdl");
proxyFb.setServiceClass(ICyfClient.class);

//proxyFb.getOutInterceptors().add(new AddPptSoapHeader()); 用于在客户端请求时在soaphead添加验证信息
ICyfClient iCyfClient = (ICyfClient)proxyFb.create();
return iCyfClient.Cnm();
***********************************************************************************************************
名词解释:转自网络
JAX-WS :
        JAX-WS规范是一组XML web services的JAVA API,JAX-WS允许开发者可以选择RPC-oriented或者message-oriented 来实现自己的web services。
  在 JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP,在使用JAX-WS过程中,开发者不需要编写任何生成和处理SOAP消息的代码。JAX-WS的运行时实现会将这些API的调用转换成为对应的SOAP消息。
  在服务器端,用户只需要通过Java语言定义远程调用所需要实现的接口SEI(service endpoint interface),并提供相关的实现,通过调用JAX-WS的服务发布接口就可以将其发布为WebService接口。
  在客户端,用户可以通过JAX-WS的API创建一个代理(用本地对象来替代远程的服务)来实现对于远程服务器端的调用。
  当然 JAX-WS 也提供了一组针对底层消息进行操作的API调用,你可以通过Dispatch 直接使用SOAP消息或XML消息发送请求或者使用Provider处理SOAP或XML消息。
  通过web service所提供的互操作环境,我们可以用JAX-WS轻松实现JAVA平台与其他编程环境(.net等)的互操作。
代码优先(Code First)或者 WSDL 优先(WSDL First):
       大家知道,如果我们要将一个服务发布一个WebService,我们需要定义这个服务所支持的方法,以及调用这些方法所提供的参数并将其转化成为 WSDL,供其它的客户端调用。Code First是第一代的WebService开发工具所提供的构建WebService的一种方式。以Java为例,我们可以通过Interface定义一 组Web服务所提供的方法,Code First就是通过获取这个Interface的信息构建出Web Services 所需要的信息,并在这些信息的基础上生成WSDL。
       而WSDL First就是通过WSDL文件,生成相关的Aritifacts,例如有相关的接口以及实现的代码框架等,这CORBA开发一样,先使用IDL描述我们 的CORBA服务,通过IDL2XXX生成相关的接口和实现框架(屏蔽了网络传输中Marshal和Unmarshal的操作)。
这两种构建Web Services各有特点,适合在不同的场景。

 

0 0
原创粉丝点击