`

cxf开发实践(服务器)

 
阅读更多

安装

CXF与其它Java类库一样,安装方法是将它的包文件复制到目标系统的${CLASSPATH}文件夹中。因为CXF依赖于其它许多Java类库,比如SpringWSDL4J等,所以需要安装的类库很多,都可以在CXF的二进制安装包的lib文件夹中找到。如果知道系统的规模,可以对依赖的类库进行删减。

在典型的配置下,要将CXF集成到已有的Web应用程序时,只需要把包文件复制到WEB-INF/lib下。

开发服务

我们知道,利用Java开发一个业务系统或者Web应用系统,通常使用利用MVC模式将系统分解为四个层次:表示层、控制层、业务逻辑层和数据访问与存储层。表示层与控制层通常对应Struts或者Swing等一些MVC框架,而业务逻辑层和数据访问与存储层对应EJB或者Spring+Hibernate等框架。Web Service属于控制层,它向外部系统暴露业务逻辑层的访问。在向外部系统提供Web
Service
前应该先设计好业务逻辑层。

以下示例是一个典型的过程化的业务逻辑层。

UserService.java:
package demo.cxf;

public interface UserService {

       public void changeUserState(User user, int state);

       public boolean checkUserExists(String username);

       public void createUser(User user);

       public void cusumePremiumPoint(String username, int points);

       public void deleteUser(String username) throws NotFoundException;

       public void increasePremiumPoint(String username, int points);

       public void updateUserInformation(User user);

}

 

UserServiceImpl.java:
package demo.cxf; 

public class UserServiceImpl
implements UserService {

       public void changeUserState(User user, int state) {
              print("changeUserState");
       }

       public boolean checkUserExists(String username) {
              print("checkUserExists");
              return false;
       }

       public void createUser(User user) {
              print("createUser");
              print(user.getUsername());
       }

       public void cusumePremiumPoint(String username, int points) {
              print("consumePremiumPoint");
       }

       public void deleteUser(String username) throws NotFoundException {
              throw new NotFoundException("我故意没找到"); 
       }

       public void increasePremiumPoint(String username, int points) {
              print("increasePremiumPoint"); 
       }

       public void updateUserInformation(User user) {
              print("updateUserInformation"); 
       }

       private void print(Object o) { 
              System.out.println(o); 
       }

}

 

User.java:

package demo.cxf;
import java.util.Date;
public class User {
       private Date birthday;
       private int height;

       private String password;
       private String sex;
       private String sign;
       private String username;

       public Date getBirthday() {
              return birthday;
       }

       public void setBirthday(Date birthday) {
              this.birthday = birthday;
       }

       public int getHeight() { 
              return height;
       }

       public void setHeight(int height) {
              this.height = height;
       }

       public String getPassword() {
              return password;
       }

       public void setPassword(String password) {
              this.password = password;
       }

       public String getSex() {
              return sex;
       }

       public void setSex(String sex) {
              this.sex = sex;
       }

       public String getSign() {
              return sign;
       }

       public void setSign(String sign) {
              this.sign = sign;
       }

       public String getUsername() {
              return username;
       }

       public void setUsername(String username) {
              this.username = username;
       }

}

 

NotFoundException.java

package demo.cxf;

public class NotFoundException
extends Exception {
       public NotFoundException() {
              super();
       }

       public NotFoundException(String message, Throwable cause) {
              super(message,cause);
       }

       public NotFoundException(String message) {
              super(message);
       }

       public NotFoundException(Throwable cause) {
              super(cause);
       }

}

 

几个小的注意事项:

l        
接口最好不包含内嵌类或者枚举类型,CXF不能识别它们

l        
接口抛出的异常也将被CXF识别并导出

3添加JAX-WS标注到Java代码中

在设计好逻辑层之后,就可以动手为逻辑层添加JAX-WS标注,以便使用CXF的代码生成工具将Java代码导出为WSDL定义。

TODO 介绍JAX-WS

JAX-WS定义了很多的标注,可以对导出的服务接口进行定义。其中较常用的是

l        
@WebService,必选的标注。用于导出的服务接口及其实现类

name

定义导出的服务接口的名字,对应于WSDL文档中wsdl:portType。默认是服务接口的Java类名加PortType

targetNamespace

定义导出的服务接口的名域(namespace),默认是倒置的服务接口Java包名。如demo.cxf.UserService的名域将会是http://cxf.demo/

serviceName

定义服务名,与名域一起唯一标识一个服务。默认是其Java类名

wsdlLocation

WSDL文档URL。可由服务器容器自动产生

endpointInterface

指定服务接口的Java类。通常用于服务实现类的标注。应当指定类的全名,如demo.cxf.UserService

portName

对应WSDL文档中的wsdl:port元素。默认是Java类名加Port

 

l        
@WebMethod,可选的标注,用于服务接口的方法

operationName

指定方法在WSDL文档中的名字,客房端用此名字调用方法

action

TODO 翻译此说明

Specifies the value of the soapAction attribute of the soap:operation
element generated for the method. The default value is an empty string.

exclude

生成WSDL文档时将该方法排除在外

 

l        
@SOAPBinding,可选的标注,用于指定生成的SOAP定义文档风格。关于此标注再详细的信息请查阅SOAP标准等参考资料

style

Style.DOCUMENT (默认)

Style.RPC

SOAP消息风格

use

Use.LITERAL (默认)

Use.ENCODED

SOAP数据编码方式

parameterStyle

ParameterStyle.BARE

ParameterStyle.WRAPPED (默认)

TODO 翻译此说明

Specifies how the method parameters, which correspond to message
parts in a WSDL contract, are placed into the SOAP message body. A parameter
style of BARE means that each parameter is placed into the message body as a
child element of the message root. A parameter style of WRAPPED means that
all of the input parameters are wrapped into a single element on a request
message and that all of the output parameters are wrapped into a single
element in the response message. If you set the style to RPC you must use the
WRAPPED parameter style.

l        
@RequestWrapper,可选的标注,用于指定如何包装客户端调用服务方法使用的参数

l        
@ResponseWrapper,可选的标注,用于指定如何包装客户端调用服务方法的返回值

l        
@WebFault,可选的标注,用于注解服务接口方法抛出的异常

name

异常的名字

targetNamespace

对应的名域,默认是服务接口的名域

faultName

实现该异类的类名

l        
@WebParam,可选的标注,用于指定方法参数的使用方式

name

WSDL文档中的名字,默认是arg0,arg1…

targetNamespace

对应的名域。默认是服务接口的名域

mode

Mode.IN (默认)Mode.OUTMode.INOUT

对于Java程序没有意义

header

true或者false(默认),指定该参数是否在SOAP消息头部发送

partName

TODO 翻译此说明

Specifies the value of the name attribute of the wsdl:part element
for the parameter when the binding is document.

 

l        
@WebResult,可选的标注,用于指定返回值的使用方式

name

返回值在WSDL文件中的名字。默认是return

targetNamespace

对应的名域。默认是服务接口的名域

header

true或者false(默认),指定该参数是否在SOAP消息头部发送

partName

TODO 翻译此说明

Specifies the value of the name attribute of the wsdl:part element
for the parameter when the binding is document.

 

一个使用了所有标注的示例:

package org.apache.cxf;

import javax.jws.*;
import javax.xml.ws.*;
import javax.jws.soap.*;

import javax.jws.soap.SOAPBinding.*;
import javax.jws.WebParam.*; 

@WebService(name="quoteReporter")
@SOAPBinding(style=Style.RPC,use=Use.LITERAL)

public interface quoteReporter
{
@WebMethod(operationName="getStockQuote")
@RequestWrapper(targetNamespace="http://demo.iona.com/types",className="java.lang.String")
@ResponseWrapper(targetNamespace="http://demo.iona.com/types",className="org.eric.demo.Quote")
@WebResult(targetNamespace="http://demo.iona.com/types",name="updatedQuote")

public Quote getQuote(

@WebParam(targetNamespace="http://demo.iona.com/types",name="stockTicker",mode=Mode.IN) 
String ticker
);

}

 

4使用java2wsdl工具生成WSDL文件

一旦为服务接口与服务实现类添加好适当的标注后,有两种方法可以得到对应的WSDL文件。一是使用CXF提供的java2wsdl命令行。二是把服务发布到Web容器,由Web容器自动生成WSDL文件。后者比较简单。比如本文的例子发布到http://server/cxf/UserService,那么可以使用http://server/cxf/UserService?wsdl这个URL得到对应的WSDL文档。下面是一个使用java2wsdl工具的例子:

WEB-INF/classes>
path D:/ develop/resource/apache-cxf-2.0.1-incubator/bin;%PATH%
WEB-INF/classes>
set CLASSPATH=.: D:/ develop/resource/apache-cxf-2.0.1-incubator/lib
WEB-INF/classes>
java2wsdl demo.cxf.UserService
WEB-INF/classes>
copy UserServiceSerivce.wsdl d:/ws

运行完毕,可以看到生成名为UserServiceService.wsdlWSDL文件。

5使用wsdl2java工具生成调用桩代码

用命令行java2wsdl生成的WSDL文件并不一定是正确的,因为它可能没有包含正确的WebService地址,但是没关系,我们先生成调用桩代码。

D:/ws>
path D:/ develop/resource/apache-cxf-2.0.1-incubator/bin;%PATH%
D:/ws>
set CLASSPATH=.: D:/ develop/resource/apache-cxf-2.0.1-incubator/lib
D:/ws>
wsdl2java ?client ?compile UserServiceService.wsdl

此时ws将有一个文件夹demo包含调用桩代码及编译后的class文件

wsdl2java还有其它命令行选项:

-server

生成服务接口

-client

生成调用桩代码

-impl

生成服务实现代码

-compile

生成代码后编译

-ant

生成ant自动构建脚本

-quiet

静默模式,不输出警告与错误信息

 

配置服务运行环境

Web Service一般使用SOAP协议将服务暴露为Web服务器[1]CXF对此提供了广泛的支持,可以使用TOMCAT、这样的Web服务器,也可以使用CXF集成的Jetty Web服务器。两者的配置过程是类似的。因为Web应用系统比较常见,所以这里介绍前一种方式。

将代码编译成功并发布到Web容器上,然后定义一个Spring的配置文件,假如名字为beans.xml,内容是:

<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" />

        <jaxws:endpoint id="UserService" implementor="demo.cxf.UserServiceImpl" address="/UserService"></jaxws:endpoint>

</beans>

 

这个配置文件首先定导入CXF预定义的配置文件,然后利用<jaxws:endpoint/>定义一个Web Service。它有如下属性:

implementor

服务实现类

address

Web Service地址,实际地址还要加上Web应用程序的地址。如本例中Web应用程序配置在/cxf下,那么UserService的地址是http://server:8080/cxf/UserService

接着在Web应用程序的web.xml配置文件中加入下列配置:

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

<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
       http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

       <context-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>WEB-INF/beans.xml</param-value>
       </context-param>

       <listener>
              <listener-class>
                     org.springframework.web.context.ContextLoaderListener
              </listener-class>
       </listener>

       <servlet>
              <servlet-name>CXFServlet</servlet-name>
              <servlet-class>
                     org.apache.cxf.transport.servlet.CXFServlet
              </servlet-class>

              <load-on-startup>1</load-on-startup>
       </servlet>

       <servlet-mapping>
              <servlet-name>CXFServlet</servlet-name>
              <url-pattern>/*</url-pattern>
       </servlet-mapping>
</web-app>

 

可以看到,CXF使用了Spring来发布服务,因此需要在WEB-INF/lib中加入Spring的类库。重启Web应用程序后可以用http://localhost:8080/<应用程序名>/UserService?wsdl 得到服务接口的WSDL文档。之前用工具生成的WSDL文档可能包含不正确的服务地址,现在把它更新一下。在WSDL文档中查找<soap:address/>标签。更改为:

<soap:address
location="http://server:8080/cxf/UserService"/>

编写Web Service客户端

至此,我们已经可以写一个UserService的客户端了。代码如下:

UserServiceTest.java:
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import demo.cxf.NotFoundException_Exception;
import demo.cxf.User;
import demo.cxf.UserService;
import demo.cxf.UserServiceService; 

public class UserServiceTest {
       public static void main(String[] args) throws MalformedURLException {
              UserServiceService uss=new UserServiceService(new
URL("file:d://ws//UserServiceService.wsdl"),

new QName("http://cxf.demo/","UserServiceService"));

              UserService myus=uss.getUserServicePort();
              User u=new User();
              u.setUsername("fish");
              myus.createUser(u);
       }
}

 

客户端程序首先根据WSDL文档(file:d/ws/UserServiceService.wsdl)和一个WSDL服务全名(http://cxf.demo/UserServiceService)生成代理,然后取得UserService的代理。利用这个代理,我们就可以像本地代码一样调用服务器的业务逻辑层了。这个代码没有什么稀奇之处,通常可以完全满足使用。如果需要深入桩代码内部,CXF提供了很多辅助类。

分享到:
评论

相关推荐

    使用CXF开发WebService服务器端和客户端

    学习CXF开发Web服务时,可以按照以下步骤进行实践: 1. 创建服务接口和实现。 2. 编写Spring配置文件,配置CXF服务器。 3. 打包并部署到应用服务器。 4. 使用wsdl2java生成客户端代码。 5. 编写客户端程序,调用Web...

    cxf开发webservice客户端和服务器端文档

    cxf开发webservice客户端和服务器端 cxf(Apache CXF)是一款开源的WebService框架,用于开发webservice客户端和服务器端。它提供了许多有用的功能,如自动生成服务桩、客户调用桩和WSDL文档等,使得开发webservice...

    cxf开发范例

    【标题】"CXF开发范例"深入解析 在IT行业中,CXF是一个广泛使用的开源框架,用于构建和消费Web服务。本范例主要涵盖了基于SOAP消息和REST风格的CXF开发,以及如何利用Spring发布SOAP和REST的Web服务。通过深入理解...

    用CXF开发SOAP接口

    【标题】"用CXF开发SOAP接口"涉及的是在Java环境中使用Apache CXF框架来创建、实现和消费基于SOAP(Simple Object Access Protocol)的Web服务。SOAP是一种用于交换结构化和类型化的信息的协议,常用于企业级应用...

    Cxf客户端及服务器端,实现客户端和服务器端的权限验证

    Apache CXF是一个开源的Java框架,主要用于构建和开发服务导向架构(SOA)和服务级应用程序。它支持多种Web服务标准,包括SOAP、RESTful API等,并提供了强大的安全功能。 首先,让我们理解权限验证的基本概念。...

    cxf开发webservice实践

    【Apache CXF 开发 WebService 实践】 Apache CXF 是一款强大的开源框架,用于构建和部署 Web Services。CXF 允许开发者通过多种协议(如 SOAP、RESTful HTTP)暴露和消费服务,使得应用程序能够轻松地与其他系统...

    cxf开发webservice服务端

    【标题】:“CXF开发Web服务端” 在Java世界中,Apache CXF是一个流行的开源框架,用于构建和部署Web服务。它支持多种Web服务规范,包括SOAP、RESTful API以及WS-*扩展。CXF允许开发者以Java SE或Java EE环境轻松...

    CXF 客户端与服务器

    【标题】:“CXF 客户端与服务器” 在Java世界中,Apache CXF是一个流行的开源框架,用于构建和开发Web服务。它不仅支持SOAP,还支持RESTful API的实现,使得开发者能够轻松地创建服务提供者和服务消费者。CXF框架...

    CXF开发webservice服务端

    ### CXF 开发 WebService 服务端详解 #### 一、引言 随着企业级应用对服务化的不断追求,Web Service 成为了...同时,随着实践经验的积累,开发者还可以进一步探索CXF框架提供的更多高级功能,以满足不同的业务需求。

    CXF开发实例.pdf

    根据文件提供的内容,本篇文档是关于Apache CXF开发实例的详细说明,主要包含了Web服务的创建、部署以及相关技术的介绍。下面将分别详细阐述以下几个方面的知识点: ### CXF基础知识 Apache CXF是一个开源的服务...

    cxf开发教程2

    "CXF开发教程2"旨在帮助开发者深入理解CXF的客户端和服务端开发,通过实践"Cxf_Client"和"Cxf_Server"示例,可以熟练掌握CXF的使用,为实际项目中的Web服务开发打下坚实基础。无论你是初学者还是经验丰富的开发者,...

    使用cxf 开发webService 初体验

    【标题】:“使用CXF开发Web Service初体验” 在Java世界中,开发Web Service是一项常见的任务,Apache CXF是一个强大的开源框架,它使得这个过程变得简单而高效。本篇文章将探讨如何利用CXF来创建和消费Web ...

    spring集成cxf客户端和服务器端demo

    总之,“spring集成cxf客户端和服务器端demo”项目为我们提供了一个基础的框架,用于理解如何在Spring环境中使用CXF开发和消费Web服务。通过实践这个示例,开发者能够掌握这两款工具的整合技术,从而在实际项目中更...

    WebService之CXF开发指南.rar

    **WebService之CXF开发指南** 在IT行业中,WebService是一种基于开放标准(如WSDL、SOAP和UDDI)的通信协议,它允许不同系统之间进行互操作性交互。CXF,全称Apache CXF,是一个开源的Java框架,用于构建和开发高...

    运用spring和CXF开发webservice

    总结来说,结合Spring和CXF开发Web服务是一种高效且灵活的方法,它利用了Spring的管理和配置优势以及CXF的Web服务实现功能。通过这种方式,你可以构建出健壮的、可扩展的Web服务,轻松地与其他系统进行数据交换。

    CXF实现简单的WebService接口开发

    通过阅读相关的博客和实践上述步骤,你可以深入理解CXF的工作原理,并掌握使用CXF开发WebService的基本流程。"利用CXF实现简单的WebService"这个文件名可能包含了一个实际的示例项目,下载后可以作为学习和调试的...

    SpringBoot开发WebService之CXF示例

    在本文中,我们将深入探讨如何使用SpringBoot集成Apache CXF来开发Web服务。SpringBoot以其简洁的配置和快速的应用启动而受到广大开发者的欢迎,而CXF是一个强大的开源框架,用于构建和消费Web服务。结合这两者,...

Global site tag (gtag.js) - Google Analytics