`
ootabc
  • 浏览: 110788 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

web service 之 CXF(1)

阅读更多
理解Web Service
什么是 Web Service 
Web Service 是为其它应用提供数据和服务的应用逻辑单元,应用程序通过标准的Web 协议和数据格式获得Web Service,如HTTP 、XML 和SOAP 等,每个Web Service 的实现是完全独立的。
简单地讲,Web 服务是一个URL 资源,客户端可以通过编程方式请求得到它的服务,而不需要知道所请求的服务是怎样实现的。 
调用 Web Service
每个Web Service 都有一个描述文件(WSDL )
它描述 一个 Web Service 的如下方面:
   (1)服务的端口(接收SOAP消息的端口)
   (2)服务提供的操作
   (3)操作的输入输出格式的定义(通过XMLSchema定义输入输出格式)
    有了Web Service 的描述文件(WSDL),我们就知道怎样调用这个Web Service 中定义的操作了。
   (1)通过服务提供的操作找到你想调用的操作
   (2)找到这个操作的输入格式的定义(XMLSchema),按照这种输入格式构造一个SOAP消息
   (3)将这个SOAP消息发送到服务的指定端口
   (4)准备接收一个从Web Service服务器返回的 SOAP 响应吧 !
Web Service服务器
一个Web Service服务器,本质上和一个Web服务器是相同的。
它主要做下面这些事: 
 监听网络端口(监听服务端口) 
 接收客户端请求(接收SOAP请求) 
 解析客户端请求(解析SOAP消息,将SOAP消息转换为数据对象)
 调用业务逻辑 (调用Web Service实现类的特定操作,参数是由SOAP消息转换而来的数据对象)
 生成响应 (将返回值转换为SOAP消息)
 返回响应 (返回SOAP响应)
Web Service客户端
一个Web Service客户端,顾名思义是和一个Web Service服务器进行交互。
下面是一个Web Service客户端调用Web Service的基本过程。
 构造SOAP请求消息
 发送SOAP消息到Web Service服务器的指定端口
 接收SOAP响应消息 
 将SOAP响应消息转换为本地数据对象
CXF 简介
Apache CXF 是一个开源的 Services 框架,CXF 帮助您利用 Frontend 编程 API 来构建和开发 Services ,像 JAX-WS 。这些 Services 可以支持多种协议,比如:SOAP、XML/HTTP、RESTful HTTP 或者 CORBA ,并且可以在多种传输协议上运行,比如:HTTP、JMS 或者 JBI,CXF 大大简化了 Services 的创建,同时它继承了 XFire 传统,一样可以天然地和 Spring 进行无缝集成。
CXF 包含了大量的功能特性,但是主要集中在以下几个方面:
支持 Web Services 标准:CXF 支持多种 Web Services 标准,包含 SOAP、Basic Profile、WS-Addressing、WS-Policy、WS-ReliableMessaging 和 WS-Security。
Frontends:CXF 支持多种“Frontend”编程模型,CXF 实现了 JAX-WS API (遵循 JAX-WS 2.0 TCK 版本),它也包含一个“simple frontend”允许客户端和 EndPoint 的创建,而不需要 Annotation 注解。CXF 既支持 WSDL 优先开发,也支持从 Java 的代码优先开发模式。
支持二进制和遗留协议:CXF 的设计是一种可插拨的架构,既可以支持 XML ,也可以支持非 XML 的类型绑定,比如:JSON 和 CORBA。
WSDL
    WSDL(Web Service Description Language)Web服务器描述语言是用XML文档来描述Web服务的标准,是Web服务的接口定义语言,由Ariba、Intel、IBM、MS等共同提出,通过WSDL,可描述Web服务的三个基本属性:
•服务做些什么——服务所提供的操作(方法)
•如何访问服务——和服务交互的数据格式以及必要协议
•服务位于何处——协议相关的地址,如URL
WSDL 文档将Web服务定义为服务访问点或端口的集合。在 WSDL 中,由于服务访问点和消息的抽象定义已从具体的服务部署或数据格式绑定中分离出来,因此可以对抽象定义进行再次使用:消息,指对交换数据的抽象描述;而端口类型,指操作的抽象集合。用于特定端口类型的具体协议和数据格式规范构成了可以再次使用的绑定。将Web访问地址与可再次使用的绑定相关联,可以定义一个端口,而端口的集合则定义为服务。因此,WSDL 文档在Web服务的定义中使用下列元素:
 Types - 数据类型定义的容器,它使用某种类型系统(一般地使用XML Schema中的类型系统)。
 Message - 通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构。
 Operation - 对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对。
 PortType - 对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持。
 Binding - 特定端口类型的具体协议和数据格式规范的绑定。
 Port - 定义为协议/数据格式绑定与具体Web访问地址组合的单个服务访问点。
 Service - 相关服务访问点的集合。
一个WSDL文件
    <?xml version="1.0" encoding="UTF-8" ?>
- <wsdl:definitions name="CountImplService" targetNamespace="http://impl.server/" xmlns:ns1="http://server/" xmlns:ns2="http://cxf.apache.org/bindings/xformat" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://impl.server/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:import location="http://localhost:8080/mycxf/count?wsdl=Count.wsdl" namespace="http://server/" />
-<wsdl:binding name="CountImplServiceSoapBinding" type="ns1:Count">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
- <wsdl:operation name="multiply">
  <soap:operation soapAction="" style="document" />
- <wsdl:input name="multiply">
  <soap:body use="literal" />
  </wsdl:input>
- <wsdl:output name="multiplyResponse">
  <soap:body use="literal" />
  </wsdl:output>
  </wsdl:operation>
- <wsdl:operation name="subtract">
  <soap:operation soapAction="" style="document" />
- <wsdl:input name="subtract">
  <soap:body use="literal" />
  </wsdl:input>
- <wsdl:output name="subtractResponse">
  <soap:body use="literal" />
  </wsdl:output>
  </wsdl:operation>
- <wsdl:operation name="divide">
  <soap:operation soapAction="" style="document" />
- <wsdl:input name="divide">
  <soap:body use="literal" />
  </wsdl:input>
- <wsdl:output name="divideResponse">
  <soap:body use="literal" />
  </wsdl:output>
  </wsdl:operation>
- <wsdl:operation name="add">
  <soap:operation soapAction="" style="document" />
- <wsdl:input name="add">
  <soap:body use="literal" />
  </wsdl:input>
- <wsdl:output name="addResponse">
  <soap:body use="literal" />
  </wsdl:output>
  </wsdl:operation>
  </wsdl:binding>
- <wsdl:service name="CountImplService">
- <wsdl:port binding="tns:CountImplServiceSoapBinding" name="CountImplPort">
  <soap:address location="http://localhost:8080/mycxf/count" />
  </wsdl:port>
  </wsdl:service>
  </wsdl:definitions>

SOAP
SOAP(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交换信息的简单的协议,是一个基于XML的协议,它包括四个部分:SOAP封装(envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架;SOAP编码规则(encoding rules),用于表示应用程序需要使用的数据类型的实例; SOAP RPC表示(RPC representation),表示远程过程调用和应答的协定;SOAP绑定(binding),使用底层协议交换信息。
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:divideResponse xmlns:ns2="http://server/">
<return>7</return>
</ns2:divideResponse></soap:Body></soap:Envelope>
JAXB
JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。
@XmlRootElement 
表示 xml 文件的根元素
@XmlElement     
表示xml 文件中的元素
@XmlAccessorType 
说明类内,什么样的成员是可以被xml转化传输的 ,可以是FIELD或 PROPERTY,具体格式如下:             
@XmlAccessorType(XmlAccessType.PROPERTY)或@XmlAccessorType(XmlAccessType. FIELD)
@XmlTransient
@XmlTransient 注释对于解决 JavaBean 属性名称与字段名称之间的名称冲突,或者用于防止字段/属性的映射。当取消首字母大写的 JavaBean 属性名称与字段名称相同时,就可能发生名称冲突。如果 JavaBean 属性引用该字段,那么可以通过防止映射使用 @XmlTransient 注释的字段或 JavaBean 属性来解决名称冲突。
@XmlJavaTypeAdapter(AddressAdapter.class)
表示当被暴露的接口传进来的参数是一个接口时,需要用它来指定其具体实现。
CXF与Spring
CXF可以天然地和 Spring 进行无缝集成,其配置如下:
Spring服务器端配置文件

<!--必须要加  在cxf-2.2.7.jar里的META-INF-cxf-osgi文件夹下可以找到-->
<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" />

<!-- intercepttor -->
<bean id ="LongingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
<bean id ="LongingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
<!--
注意:<jaxws:server id="surveyService" implementor="ws.cxf.impl.SurveyService"
address="/SurveyWebService" />

    id:指在spring配置的bean的ID.

Implementor:指明具体的实现类.

Address:指明这个web service的相对地址,
-->
<jaxws:endpoint id="count" implementor="server.impl.CountImpl" address="/count">
<jaxws:inInterceptors>
<ref bean ="LongingInInterceptor"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean ="LongingOutInterceptor"/>
</jaxws:outInterceptors>

</jaxws:endpoint> -


客户端bean.xml
<!-- 定义一个工厂  -->
<bean id="counter" class="server.Count" factory-bean="clientFactory"
factory-method="create" />
<!-- 创建实例  -->
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="server.Count" />
<property name="address" value="http://localhost:8080/mycxf/count" />
</bean>

Web.xml
  
<!-- Spring 配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/serverBean.xml</param-value>
</context-param>
<!-- Spring ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Apache CXFServlet -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<!-- CXFServlet Mapping -->
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

一个CXF实例
实例使用CXF 2.2.7,实现远程调用加减乘除及基本的拦截器
Count.java
  
package server;

import javax.jws.WebService;

@WebService
public interface Count {

/**
* 进行加减乘除
* @param a
* @param b
* @return
*/
public int add(int a,int b);

public int subtract(int a,int b);

public int multiply(int a,int b);

public int divide(int a,int b);
}
CountImpl.java
  
package server.impl;

import javax.jws.WebService;

import server.Count;
@WebService(endpointInterface = "server.Count")
public class CountImpl implements Count {

public int add(int a, int b) {
return a+b;
}

public int divide(int a, int b) {
return a-b;
}

public int multiply(int a, int b) {
return a*b;
}

public int subtract(int a, int b) {
return a/b;
}

}}
ServerBean.xml
  <?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:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:util="http://www.springframework.org/schema/util" 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/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.0.xsd"
default-lazy-init="false">

<!--必须要加  在cxf-2.2.7.jar里的META-INF-cxf-osgi文件夹下可以找到-->
<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" />

<!-- intercepttor -->
<bean id ="LongingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
<bean id ="LongingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
<!--
注意:<jaxws:server id="surveyService" implementor="ws.cxf.impl.SurveyService"
address="/SurveyWebService" />

    id:指在spring配置的bean的ID.

Implementor:指明具体的实现类.

Address:指明这个web service的相对地址,
-->
<jaxws:endpoint id="count" implementor="server.impl.CountImpl" address="/count">
<jaxws:inInterceptors>
<ref bean ="LongingInInterceptor"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean ="LongingOutInterceptor"/>
</jaxws:outInterceptors>

</jaxws:endpoint>
</beans>
}}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="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">
<!-- Spring 配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/serverBean.xml</param-value>
</context-param>
<!-- Spring ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Apache CXFServlet -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<!-- CXFServlet Mapping -->
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

</web-app>
}}
ClientMain.java
package client;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import server.Count;

public class ClientMain {

public static void main(String[] args){

ClassPathXmlApplicationContext con = new ClassPathXmlApplicationContext("client/clientbeans.xml");
System.out.println("-------加载属性文件成功-------");
Count coun =(Count)con.getBean("counter");
System.out.println(coun.add(1, 1));
int a = coun.divide(8,1);
System.out.println(a);
}
}
ClientBean.xml
<?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-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">

<!-- 定义一个工厂  -->
<bean id="counter" class="server.Count" factory-bean="clientFactory"
factory-method="create" />
<!-- 创建实例  -->
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="server.Count" />
<property name="address" value="http://localhost:8080/mycxf/count" />
</bean>

</beans>
要注意的问题
服务端不能返回接口,如果要返回类型是接口必须用注释 @XmlJavaTypeAdapter(AddressAdapter.class) 来指定其具体实现类

遇到的问题
Hashtable<String,String>传递:
当CXF返回一个Map<String,String>类型的值时,客户端不能接收到里面相应的值
解决方法1:
用Bean对象将其封装
不能传递Hashtable<String, Hashtable <String,String>>.
解决办法1:
将其拆分为两个Hashtable<String,String>,再对其封装传递

分享到:
评论

相关推荐

    实战Web Service 之CXF

    实战Web Service 之 CXF 实战Web Service 之 CXF

    实战Web Service with CXF

    实战Web Service with CXF cxf非常好的ppt教程

    Web service之CXF-helloworld DEMO

    1. **设置环境**:确保你已经安装了Java Development Kit (JDK) 和 Apache Maven,这两个是CXF开发的基础工具。同时,你也需要在你的项目中引入CXF的依赖。这通常通过在`pom.xml`文件中添加对应的Maven依赖来完成。 ...

    Apache CXF开发Web Service 理解CXF Frontends之Code-First

    Apache CXF是一个开源的Java框架,它用于构建和开发Web服务。这个框架提供了一种灵活的方式来进行服务的创建、发布和调用。"Code-First"是CXF的一个重要概念,意味着开发者首先编写Java代码,然后CXF会自动生成相应...

    web service开发 cxf框架帮助文档

    1. **易用性**:CXF提供了直观的API和工具,使得开发者能够轻松地创建和消费Web服务。 2. **灵活性**:支持多种Web服务风格,包括SOAP、RESTful、JAX-RS、JAX-WS等。 3. **集成能力**:无缝集成Spring框架,便于服务...

    Apache CXF开发Web Service 理解CXF Frontends之Contract-First

    在"Apache CXF开发Web Service理解CXF Frontends之Contract-First"的主题中,我们将深入探讨以下几个关键知识点: 1. **Web服务基础**:Web服务是一种通过网络进行通信的应用程序接口,使用标准协议如SOAP(简单...

    Apache CXF Web Service Development(源码)

    【标题】中的"Apache CXF Web Service Development"指的是使用Apache CXF框架进行Web服务开发的过程。这通常包括了创建服务接口、实现服务逻辑、配置服务端点、以及发布和调用服务等步骤。源码部分可能包含了示例...

    CXF开发Web Service实例demo

    在"Web Service学习-CXF开发Web Service实例demo(一)"中,我们将专注于SOAP Web Service的实现。以下是一些关键步骤: 1. **创建服务接口**:首先,你需要定义一个Java接口,这个接口会成为你的Web Service接口。...

    Web Service 之cxf2.4.10版整合spring-3.1.3示例项目代码

    1、解压cxf-spring-server文件后发布到tomcat服务器上(服务端) 2、解压cxf-spring-client文件后导入eclipse中运行cn.com.songjy.ws.main.ClientMain即可测试(客户端) 备注:便于测试,请将的端口为设置为8008,...

    CXF Web Service & client

    本篇将深入探讨如何利用CXF来开发Web Service及其客户端,以及相关的重要知识点。 ### 1. CXF简介 Apache CXF是一个全面的服务框架,支持多种Web服务规范,如SOAP、RESTful API、WS-*(如WS-Security、WS-...

    web service cxf spring集成

    标题"Web Service CXF Spring集成"表明我们将探讨如何在Spring环境中利用Apache CXF来创建和整合Web服务。首先,你需要在项目中引入CXF和Spring的相关依赖。通常,这可以通过在Maven或Gradle的配置文件中添加相应的...

    web service cxf获取第三方天气数据

    1. 安装和配置CXF库:确保项目的`pom.xml`或`build.gradle`文件中添加了CXF的依赖。 2. 生成Java客户端代码:使用CXF的命令行工具或Maven插件,从`WeatherWS.wsdl`生成Java源代码。 3. 编写测试代码:在`MainTest....

    web service cxf 2.7.5 与spring 3.0 集成

    提供的`cxf_service`文件可能包含了CXF运行时所需的集合,如JAXB绑定类、WSDL文件、XSD schema等。这些文件对于构建和运行Web服务至关重要。 **六、客户端调用** 使用Spring的JAX-WS客户端代理工厂...

    Spring MVC、CXF、Web Service

    Spring MVC、CXF和Web Service是企业级Java应用开发中的三个关键组件,它们分别在不同的层面上服务于构建高效、可扩展的Web应用程序。 Spring MVC,全称Spring Model View Controller,是Spring框架的一部分,专为...

    CXF框架应用在Web项目中

    Ⅰ)调用CXF提供的wsdl2java工具,根据WSDL文档生成相应的Java代码(任何语言实现web service都要暴露WSDL文档); Ⅱ)找到wsdl2java所生成的类中一个继承了Service的类(该类的实例可当工厂使用); Ⅲ)调用...

Global site tag (gtag.js) - Google Analytics