`
reymont
  • 浏览: 529516 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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

阅读更多

CXF前端(Frontend)是编程使用的API,用来开发和对外暴露Web ServicesCXF提供两种类型的前端(Frontend):JAX-WS和简单前端(Simple Frontend)。本节将详细介绍JAX-WS前端。

 

JAX-WS前端

Code-First方式

创建Service Endpoint Interface ( SEI)

添加Java注解

发布服务

开发客户端

运行Web Service

 

 

 

JAX-WS前端

 

CXF支持由Java Community Process (JCP)提供的JAX-WS 2.0 API规范。CXF实现了JAX-WS规范。

 

JAX-WS提供了两种方式来创建Web ServiceCode-FirstContract-First

 

Code-First:先创建Java类然后基于Java类生成Web Service组件。一般用于输入/输出对象格式简单,并希望快速部署应用。Code-First的方式正如开发普通的JAVA应用一样,不用关心WSDLXSD的生成,也不必维护JAVA对象和XML元素的映射关系。只需要在JAVA类中注明,CXF中的工具Java2WSDL会为你完成这些工作。

 

Contract-First:开发者基于WSDL规范来编写将要暴露的Web ServiceContract-First的方式适用于你已经定义好Web Service操作的输入/输出的消息格式,或者想更好的控制XMLJAVA对象之间的映射关系。Contract-First开发模式要求你精通XSDWSDL规范。

 

想更深一步了解请看:《代码优先(Code-First)和契约优先(Contract-First)的比较

 

 

 

Code-First方式:

 

Code-First方式需求完成的工作有:

创建Service Endpoint Interface ( SEI)

添加Java注解

发布服务

开发客户端

 

创建Service Endpoint Interface ( SEI)

 

Service Endpoint InterfaceJAVA Interface类似,定义了业务的服务方法。你可以从零开始开发SEI,或者将现有的业务功能转换为基于服务的组件。

 

从零开始就是说,没有任何代码或WSDL约束,重新开发Web Service。适用于先创建接口后编写实现代码。将现有代码转换,就是利用已经存在的业务功能,将其转换为基于服务的组件。大部分情况是我们拥有已经实现好的业务逻辑,只是需要将其暴露为Web Service方法。我们可以开发SEI并定义哪些业务方法需要暴露出去,很轻松的实现普通业务到基于服务的转变。

 

使用《Apache CXF开发Web Service 开发Web ServiceKick Start》中提到的例子。

 

package demo.order;

 

import javax.jws.WebService;

 

@WebService

public interface OrderProcess {

    String processOrder(Order order);

}

 

package demo.order;

 

import javax.jws.WebService;

 

@WebService(serviceName="OrderProcessService", portName="OrderProcessPort")

public class OrderProcessImpl implements OrderProcess {

 

    public String processOrder(Order order) {

       String orderID = validate(order);

       System.out.println("Processed order..." + orderID);

        return orderID;

    }

 

    /**

     * Validates the order and returns the order ID

    **/

    private String validate(Order order) {

       String custID = order.getCustomerID();

       String itemID = order.getItemID();

       int qty = order.getQty();

       double price = order.getPrice();

 

       if (custID != null && itemID != null && !custID.equals("") &&

              !itemID.equals("") && qty > 0 && price > 0.0) {

           return "ORD1234";

       }

       return null;

    }

 

}

 

JAVA注解:

 

JAVA类添加Web Service注解后,暴露成服务组件。JAX-WS使用JAVA5注解,使用了Java Platform specification ( JSR-181 ).这些注解用来定义详细的组件和方法。每个注解都拥有一个或多个属性。接下来将讨论一下两个Web Serivce注解:javax.jws.WebServicejavax.jws.soap.SOAPBinding

 

JAVA组件通过添加@WebService注解来转换为服务。这个注解在SEI和实现类中均需添加。@WebService 注解由javax.jws.WebService接口定义。

 

@WebService 注解的属性有:Name, targetNamespace, serviceName, wsdlLocation, endpointInterface, portName

 

具体解释可参考http://docs.oracle.com/javase/6/docs/api/javax/jws/WebService.html

 

 

Attribute

Description

Name

Indicates the name of the service interface. It is directly mapped to a name attribute of the  <wsdl:portType> element in WSDL document. If the attribute is not provided, then the name of the service interface is taken as default

targetNamespace

It holds the namespace where the service is defined. If no namespace is provided, then the package name is taken as default

serviceName

The name of the published service object. It directly maps to a name attribute of wsdl:service element in WSDL document. The default value is the name  of the service implementation class.

wsdlLocation

It indicates the location of WSDL document in the form of URL

endpointInterface

This attribute is used by the service implementation class. It specifies the fully qualified name of the service interface which will be implemented by the service implementation class.

portName

It indicates the name of the endpoint where the service is published. It directly maps to a name attribute of the <wsdl:port> element in the WSDL document.

 

 

 

OrderProcess SEI OrderProcessImpl添加@WebService注解,如代码中黄色突出部分。值得注意的是,OrderProcessImpl中还有额外的属性

 

@WebService(serviceName="OrderProcessService", portName="OrderProcessPort")

 

serviceName被客户端用户获取远端接口存根,调用服务方法。portName指明endpoint的名称。当然剩下的属性也可以使用。这些属性完整的描述服务的细节。建议充分利用这些注解来描述Web Service,这样生成的WSDL文档将会拥有更纤细的内容。如果没有使用这些属性,如OrderProcess SEI一样,WSDL中会默认设置一些值。

 

@SOAPBinding注解由javax.jws.soap.SOAPBinding接口定义。这个注解用来指定SOAP绑定。

 

参考http://docs.oracle.com/javase/6/docs/api/index.html?javax/jws/WebService.html

 

Attribute

Description

Default

Style

Indicates the style of the SOAP

message. The attribute supports two styles, namely,  Style.DOCUMENT and  Style.RPC.

The default is DOCUMENT

Use

The attribute determines how the SOAP message is to be formatted during serialization. It supports two values, namely, Use.LITERAL and Use.ENCODED

The default is LITERAL.

parameterStyle

Indicates how the SOAP messages are to be used. The message can be either wrapped, that is, operation parameters are wrapped as child elements inside an element in the SOAP body, or it can be unwrapped as different individual elements. It supports two values, namely ParameterStyle.BARE and ParameterStyle.WRAPPED.

The default is WRAPPED.

 

Web Service SOAP通讯方式在SOAP XML消息中起着重要的作用,有两种SOAP通讯样式:DocumentRPC。在WSDL文档中由SOAP binding定义。SOAP binding可以有加密的形式或者文本的形式。如:

 

<soap:binding style="document" transport="uri">

 

Document样式处理XML文本。在调用过程中,整个文档在服务客户端和服务器之间进行交换,特别是使用XML Schema Definitions (XSD) 创建的XML文本。RPC ( Remote Procedure Call)样式指出SOAP body包含了XMLSOAP规范定义了一系列编码规则,用来将方法参数序列化以便被Web Service实现反序列化调用。在实际使用中尽量使用Document样式。

 

Document样式的优点:

充分利用XML易读和易扩展的特点,来描述和验证复杂的业务。而RPC执行复杂业务较为繁琐,需要包含XML文档作为参数并在调用方法中做好验证。

修改代码方便。

适用于异步处理,可以直接放到消息队列中。

使用XML交换对象,无需序列化对象。

 

想更深入了解请阅读《获得文档样式 Web 服务的好处

 

一个@SOAPBinding的例子:

 

@WebService(name="OrderProcess")

@SOAPBinding(parameterSyle=ParameterStyle.BARE)

public interface OrderProcess {

    String processOrder(Order order);

}

 

发布服务:

 

发布服务意思是将服务组件注册到服务器中,客户端通过endpoint URL访问。CXF提供独立的服务器工具JaxWsServerFactoryBean,这里不做详细介绍。

 

package demo.order;

 

import javax.xml.ws.Endpoint;

 

public class Server {

 

    protected Server() throws Exception {

        System.out.println("Starting Server");

        OrderProcessImpl orderProcessImpl = new OrderProcessImpl();

        String address = "http://localhost:8080/OrderProcess";

        Endpoint.publish(address, orderProcessImpl);

    }

 

    public static void main(String args[]) throws Exception {

        new Server();

        System.out.println("Server ready...");

 

        Thread.sleep(5 * 60 * 1000);

        System.out.println("Server exiting");

        System.exit(0);

    }

}

 

Endpoint类提供了便利的静态方法来发布和测试JAX-WS Web Service。使用Endpoint URL地址和实现的方法作为参数。这个轻量级的服务器会运行5分钟后自动退出。在浏览器中输入如下内容可已看到WSDL文档。

 

http://localhost:8080/OrderProcess?wsdl

 

开发客户端:

 

package demo.order.client;

 

import java.net.URL;

import javax.xml.namespace.QName;

import javax.xml.ws.Service;

 

import demo.order.Order;

import demo.order.OrderProcess;

 

public class Client {

 

    private static final QName SERVICE_NAME = new QName("http://order.demo/", "OrderProcessService");

    private static final QName PORT_NAME = new QName("http://order.demo/", "OrderProcessPort");

 

    private static final String WSDL_LOCATION = "http://localhost:8080/OrderProcess?wsdl";

 

    public static void main(String args[]) throws Exception {

        URL wsdlURL = new URL(WSDL_LOCATION);

        Service service = Service.create(wsdlURL, SERVICE_NAME);

        OrderProcess port = service.getPort(PORT_NAME, OrderProcess.class); 

 

                   Order order = new Order();

                   order.setCustomerID("C001");

                   order.setItemID("I001");

                   order.setPrice(100.00);

                   order.setQty(20);

 

        String result = port.processOrder(order);

        System.out.println("The order ID is " + result);

            

    }

   

}

 

WSDL URL指明为http://localhost:8080/OrderProcess?wsdl

接着创建Service对象。使用Service的静态方法create来创建。服务的名称为OrderProcessService。将在WSDL文档中映射为<wsdl:service name="OrderProcessService">

然后使用Service对象,通过getPort方法获取SEI存根代码组件。Endpoint的名称为OrderProcessPort。将在WSDL文档中映射为<wsdl:port binding="tns:OrderProcessServiceSoapBinding" name="OrderProcessPort">

最后使用代理的组件port调用processOrder方法。

 

 

 

运行Web Service

 

这里使用Maven来作为构建工具。如果想立刻看到效果请使用NetBean,内置了Maven。如果使用eclipse则需要添加m2eclipse插件,参见Eclipse Maven 插件 m2eclipse

 

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

 

    <groupId>org.dcb.cxfbook.ch03</groupId>

    <artifactId>codefirst2</artifactId>

    <version>1.0</version>

    <packaging>jar</packaging>

 

    <name>codefirst</name>

    <url>http://maven.apache.org</url>

 

    <properties>

        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <cxf.version>2.2.3</cxf.version>

    </properties>

 

    <dependencies>

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>3.8.1</version>

            <scope>test</scope>

        </dependency>

        <dependency>

            <groupId>org.apache.cxf</groupId>

            <artifactId>cxf-rt-frontend-jaxws</artifactId>

            <version>${cxf.version}</version>

        </dependency>

        <dependency>

            <groupId>org.apache.cxf</groupId>

            <artifactId>cxf-rt-transports-http</artifactId>

            <version>${cxf.version}</version>

        </dependency>

        <dependency>

            <groupId>org.apache.cxf</groupId>

            <artifactId>cxf-rt-transports-http-jetty</artifactId>

            <version>${cxf.version}</version>

        </dependency>

        <dependency>

            <groupId>com.sun.xml.bind</groupId>

            <artifactId>jaxb-xjc</artifactId>

            <version>2.1.12</version>

        </dependency>

    </dependencies>

   

    <build>

        <finalName>codefirst</finalName>

        <plugins>

            <plugin>

                <artifactId>maven-compiler-plugin</artifactId>

                <configuration>

                    <source>1.5</source>

                    <target>1.5</target>

                </configuration>

            </plugin>

        </plugins>

    </build>

    <profiles>

        <profile>

            <id>server</id>

            <build>

                <defaultGoal>test</defaultGoal>

                <plugins>

                    <plugin>

                        <groupId>org.codehaus.mojo</groupId>

                        <artifactId>exec-maven-plugin</artifactId>

                        <executions>

                            <execution>

                                <phase>test</phase>

                                <goals>

                                    <goal>java</goal>

                                </goals>

                                <configuration>

                                    <mainClass>demo.order.Server</mainClass>

                                </configuration>

                            </execution>

                        </executions>

                    </plugin>

                </plugins>

            </build>

        </profile>

        <profile>

            <id>client</id>

            <build>

                <defaultGoal>test</defaultGoal>

                <plugins>

                    <plugin>

                        <groupId>org.codehaus.mojo</groupId>

                        <artifactId>exec-maven-plugin</artifactId>

                        <executions>

                            <execution>

                                <phase>test</phase>

                                <goals>

                                    <goal>java</goal>

                                </goals>

                                <configuration>

                                    <mainClass>demo.order.client.Client</mainClass>

                                </configuration>

                            </execution>

                        </executions>

                    </plugin>

                </plugins>

            </build>

        </profile>

    </profiles>

</project>

 

pom.xml中,添加cxf-rt-frontend-jaxwscxf-rt-transports-httpcxf-rt-transports-http-jetty(发布服务是需要)依赖,maven会自动加载相关的jar包,包括CXF, Spring, common, JABX, jetty。在profiles. Profile. Build. Plugins. Plugin节点添加exec-maven-plugin提供通过-Pserver-Pclient来界定命令行运行demo.order.Server demo.order.client.Client

 

cd codefirst2

#启动server,显示Server ready...消息

mvn test –Pserver

#执行client,显示The order ID is ORD1234

mvn test -Pclient

 

 

 

也可以在在IDE (Netbean or Eclipse)中直接执行运行。先执行Server,后执行Client

 

 

 

名词解释:

 

XML Schema Definition (XSD) XML Schema描述了XML文档的结构。可以用一个指定的XML Schema来验证某个XML文档,以检查该XML文档是否符合其要求。文档设计者可以通过XML Schema指定一个XML文档所允许的结构和内容,并可据此检查一个XML文档是否是有效的。XML Schema本身是一个XML文档,它符合XML语法结构。可以用通用的XML解析器解析它。

RPCRemote Procedure Call Protocol——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCPUDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层应用层RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

 

 

 

参考内容:

 

http://baike.baidu.com/view/712698.htm XSD 百科

http://baike.baidu.com/view/160660.htm WSDL百科

http://jcp.org/en/jsr/detail?id=181 JSR-181

http://baike.baidu.com/view/2742297.htm CXF百科

http://baike.baidu.com/view/160660.htm WSDL百科

http://baike.baidu.com/view/60663.htm SOAP百科

http://baike.baidu.com/view/32726.htm RPC 百科

获得文档样式 Web 服务的好处

 

 

1
3
分享到:
评论

相关推荐

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

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

    Apache CXF开发Web Service 开发Web Service之Kick Start

    "Apache CXF开发Web Service - 开发Web Service之Kick Start"的主题意味着我们将深入探讨如何快速入门使用CXF进行Web服务开发。 首先,我们来看一下CXF的主要功能。CXF支持多种Web服务规范,如SOAP、RESTful(基于...

    Apache CXF Web Service Development(源码)

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

    实战Web Service —— 使用Apache CXF开发Web服务的教程

    **实战Web Service与Apache CXF开发** Web服务是一种在互联网上进行通信的标准协议,它允许应用程序之间进行数据交换。Apache CXF是一个开源框架,用于构建和部署Web服务,支持多种Web服务标准,如SOAP、RESTful ...

    apache-cxf-3.5.0.zip

    Apache CXF 是一款广泛使用的开源框架,主要用于构建和部署高质量的Web服务。它以其灵活性、易用性和强大...通过深入理解和实践"apache-cxf-3.5.0.zip"中的内容,开发者可以更好地利用CXF构建高效、健壮的分布式系统。

    Apache CXF开发使用指南.docx

    Apache CXF 是一款开源的 Java 框架,主要用于构建和开发 Web 服务。...无论选择 WSDL-First 还是 Code-First 开发模式,Apache CXF 都能提供便捷的支持,使得在 Java 平台上开发 Web Service 变得简单易行。

    apache cxf_jar包

    9. **cxf-rt-transports-jms-2.7.12.jar**: JMS(Java Message Service)传输模块,提供了使用JMS作为Web服务传输机制的能力,这对于分布式系统和异步通信很有价值。 10. **cxf-rt-databinding-jaxb-2.7.12.jar**: ...

    CXF开发Web Service实例demo

    总的来说,通过Apache CXF开发Web Service不仅简化了开发流程,还提供了丰富的功能和良好的性能。无论是服务端还是客户端,理解并掌握CXF的使用对于提升企业级应用的互操作性和可扩展性都至关重要。

    cxf框架包 apache-cxf-3.4.3.tar.gz

    在本案例中,我们讨论的是"apache-cxf-3.4.3.tar.gz",这是Apache CXF 3.4.3版本的压缩包,通常包含了CXF框架的所有组件和必要的库文件。 **1. CXF框架介绍** Apache CXF是一个全面的服务开发框架,它的全称是...

    apache-cxf-2.4.1.rar_apache-cxf-2.4.1_cxf_web service

    这个"apache-cxf-2.4.1.rar"压缩包包含了CXF框架的2.4.1版本,这是一个在2010年左右发布的稳定版本。CXF这个名字是"CXF =CX+XF"的缩写,其中"CX"代表了"Client eXtension Framework",而"XF"则代表了"XFire",它是...

    apache-cxf-2.7.11

    在解压后的"apache-cxf-2.7.11"文件中,你将找到以下组件和资源: - **bin目录**:包含启动和配置CXF服务的脚本。 - **lib目录**:包含了CXF运行所需的库文件,包括JAR包。 - **docs目录**:存放API文档和其他技术...

    apache-cxf-2.7.6.rar

    这个"apache-cxf-2.7.6.rar"文件包含的是Apache CXF 2.7.6版本的源码、库文件和其他相关资源。CXF这个名字是“Cocoon XML Framework”的缩写,起初它是Apache Cocoon项目的一部分,后来发展成为专注于Web服务的独立...

Global site tag (gtag.js) - Google Analytics