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

2024-01-01 19:58

本文主要是介绍Apache CXF开发Web Service 理解CXF Frontends之Contract-First,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Apache CXF开发Web Service 理解CXF FrontendsCode-First》一文提到Code-FirstContract-First两种不同的方式,这里将介绍Contract-First的使用。如果使用Contract-First的开发方式,开发者首先准备好WSDL文档,通过CXF提供的工具wsdl2java来生成代码。这个工具在%CXF-HOME%/bin目录中。Contract-First需要完成的工作有:

 

生成服务组件

实现服务方法

发布Web Service

开发客户端

 

使用《Apache CXF开发Web Service 理解CXF FrontendsCode-First》中生成的WSDL文档,即启动mvn test –Pserve后,访问http://localhost:8080/OrderProcess?wsdl所看到的内容。现在是要把操作倒过去,通过这个WSDL来生成SEI

 

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

<wsdl:definitions name="OrderProcessService" targetNamespace="http://order.demo/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://order.demo/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <wsdl:types>

       <xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://order.demo/" xmlns:tns="http://order.demo/" xmlns:xs="http://www.w3.org/2001/XMLSchema">

           <xs:element name="processOrder" type="tns:processOrder" />

           <xs:element name="processOrderResponse" type="tns:processOrderResponse" />

           <xs:complexType name="processOrder">

              <xs:sequence>

                  <xs:element minOccurs="0" name="arg0" type="tns:order" />

              </xs:sequence>

           </xs:complexType>

           <xs:complexType name="order">

              <xs:sequence>

                  <xs:element minOccurs="0" name="customerID" type="xs:string" />

                  <xs:element minOccurs="0" name="itemID" type="xs:string" />

                  <xs:element name="price" type="xs:double" />

                  <xs:element name="qty" type="xs:int" />

              </xs:sequence>

           </xs:complexType>

           <xs:complexType name="processOrderResponse">

              <xs:sequence>

                  <xs:element minOccurs="0" name="return" type="xs:string" />

              </xs:sequence>

           </xs:complexType>

       </xs:schema>

    </wsdl:types>

    <wsdl:message name="processOrderResponse">

       <wsdl:part element="tns:processOrderResponse" name="parameters">

       </wsdl:part>

    </wsdl:message>

    <wsdl:message name="processOrder">

       <wsdl:part element="tns:processOrder" name="parameters">

       </wsdl:part>

    </wsdl:message>

    <wsdl:portType name="OrderProcess">

       <wsdl:operation name="processOrder">

           <wsdl:input message="tns:processOrder" name="processOrder">

           </wsdl:input>

           <wsdl:output message="tns:processOrderResponse" name="processOrderResponse">

           </wsdl:output>

       </wsdl:operation>

    </wsdl:portType>

    <wsdl:binding name="OrderProcessServiceSoapBinding" type="tns:OrderProcess">

       <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />

       <wsdl:operation name="processOrder">

           <soap:operation soapAction="" style="document" />

           <wsdl:input name="processOrder">

              <soap:body use="literal" />

           </wsdl:input>

           <wsdl:output name="processOrderResponse">

              <soap:body use="literal" />

           </wsdl:output>

       </wsdl:operation>

    </wsdl:binding>

    <wsdl:service name="OrderProcessService">

       <wsdl:port binding="tns:OrderProcessServiceSoapBinding" name="OrderProcessPort">

           <soap:address location="http://localhost:8080/OrderProcess" />

       </wsdl:port>

    </wsdl:service>

</wsdl:definitions>

 

 

 

生成服务组件

 

将准备好的WSDL文档命名为OrderProcess.wsdl。文档的内容与使用JAX-WS规范的JAVA组件对应。

 

WSDL element

Java component

targetNamespace attribute of the <wsdl:definitions>  element

targetNamespace="http://order.demo/"

Java packagedemo.order

<wsdl:portType>

<wsdl:portType name="OrderProcess">

Java Service Endpoint Interface (SEI)

OrderProcess

<wsdl:operation> child element of the  <wsdl:portType> element

<wsdl:operation name="processOrder">

Java methods

processOrder

<wsdl:service>

<wsdl:service name="OrderProcessService">

Service class

OrderProcessService

<wsdl:message>

Service operation parameters

 

关于wsdl2java工具的使用请参考:

http://cxf.apache.org/docs/wsdl-to-java.html

http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html

 

这里将介绍Maven 的插件 cxf-codegen-plugin 来生成代码的方式。Apache CXF开发Web Service 理解CXF FrontendsCode-First》文中提到的pom.xml添加cxf-codegen-plugin

 

 

<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>contractfirst</artifactId>

    <version>1.0</version>

    <packaging>jar</packaging>

 

    <name>contractfirst</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>

    </dependencies>

   

    <build>

        <finalName>contractfirst</finalName>

        <plugins>

            <plugin>

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

                <configuration>

                    <source>1.5</source>

                    <target>1.5</target>

                </configuration>

            </plugin>

            <plugin>

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

                <artifactId>cxf-codegen-plugin</artifactId>

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

                <executions>

                    <execution>

                        <id>generate-sources</id>

                        <phase>generate-sources</phase>

                        <configuration>

                            <wsdlOptions>

                                <wsdlOption>

                                    <wsdl>src/main/resources/OrderProcess.wsdl</wsdl>

                                </wsdlOption>

                            </wsdlOptions>

                        </configuration>

                        <goals>

                            <goal>wsdl2java</goal>

                        </goals>

                    </execution>

                </executions>

            </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.OrderProcessServer</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>

 

 

执行命令:

 

cd contractfirst

mvn generate-sources

 

Maven cxf-codegen-plugin会为你自动调用CXF wsdl2java工具。可能初学Maven的朋友不大理解,这里简单介绍cxf-codegen-plugin的使用。在build.plugins.plugin中添加cxf-codegen-plugin<wsdl>src/main/resources/OrderProcess.wsdl</wsdl>指明要转换的WSDL文档。<phase>generate-sources</phase>指明执行的命令。<goal>wsdl2java</goal>指明执行命令所包含的工作。

 

对于GoalPhase的关系,在《Maven中的几个重要概念()lifecycle, phase and goal》一文中有详细的介绍。这里摘选GoalPhase的内容:

 

Maven定义了一系列Best Practice,将关联的Phase组合在一起,即执行一个phase会执行某个liefcycle所有的phaseGoal是独立的,可以绑定到多个phase中,也可以不绑定。从这方面讲,phase就是goal的容器,实际被执行的是goal

 

在本文中执行generate-sources这个phase,其实是执行cxf-codegen-plugin中的<goal>wsdl2java</goal>

 

对于Maven的生命周期,请看《Maven生命周期详解》。

 

跑题了半天,让我们看看这mvn generate-sources到底生成了什么内容:

JAXB输入/输出消息类。wsdl2java类会分别生成JAVA输入/输出消息组件。本例中将会生成ProcessOrder作为输入类,生成ProcessOrderResponse作为输出类,还会根据<xs:complexType name="order">生成Order类。

服务接口。本例中服务接口为OrderProcess

服务实现类。本例中提供了继承自Service接口的实现类OrderProcessService。我们可以修改这个类来实现功能。

 

这些类都在包demo.order中。wsdl2java工具从targetNamespace="http://order.demo/"生成包名,也就是http://order.demo/除去http://后倒写。

 

如果修改pom.xml,添加如下内容,将会生成OrderProcessImpl.java(示例的实现服务类)和OrderProcess_OrderProcessPort_Server.javaCXF提供的独立的服务器)。

                            <wsdlOption>

                                <wsdl>src/main/resources/OrderProcess.wsdl</wsdl>

                                <extraargs>

                                   <extraarg>-server</extraarg>

                                   <extraarg>-impl</extraarg>

                                   <extraarg>-verbose</extraarg>

                                </extraargs>

                            </wsdlOption>

 

 

 

JAXB 输入/输出消息类

 

ProcessOrder, ProcessOrderResponseOrder这三个类代表Web Service操作类。这几个类有着各种JAXB注解。ProcessOrder ProcessOrderResponse用来表示RequestResponseRequest拥有出入参数引用,而Response着拥有输出参数引用。

 

为了理解RequestResponse的概念,来看看Web Service将会提交什么样的SOAP Request消息。

 

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

<soap:Body>

      <ns2:processOrder xmlns:ns2="http://order.demo/">

         <arg0>

            <customerID>C001</customerID>

            <itemID>I001</itemID>

            <price>200.0</price>

            <qty>100</qty>

         </arg0>

      </ns2:processOrder>

</soap:Body>

</soap:Envelope>

 

processOrder映射为Web Service中的方法processOrder。子元素arg0代表着SOAP payload,映射为输入参数OrderCXF会自动将arg0转换为Order对象,并执行processOrder方法。

 

 

 

服务接口

 

OrderProcessSEI,定义了processOrder方法。

 

@WebService(targetNamespace = "http://order.demo/", name = "OrderProcess")

@XmlSeeAlso({ObjectFactory.class})

public interface OrderProcess {

 

    @WebResult(name = "return", targetNamespace = "")

    @RequestWrapper(localName = "processOrder", targetNamespace = "http://order.demo/", className = "demo.order.ProcessOrder")

    @ResponseWrapper(localName = "processOrderResponse", targetNamespace = "http://order.demo/", className = "demo.order.ProcessOrderResponse")

    @WebMethod

    public java.lang.String processOrder(

        @WebParam(name = "arg0", targetNamespace = "")

        demo.order.Order arg0

    );

}

 

@WebService定义了这个接口是SEI

@Xml SeeAlso通知JAXB在执行数据绑定是包含ObjectFactory

@RequestWrapper包含了输入消息。

@ResponseWrapper包含了输出消息。

@WebResult指明返回的类型。

@WebMethod指明这是个服务方法。

@WebParam指明参数。

 

 

 

运行Web Service

 

Apache CXF开发Web Service 理解CXF FrontendsCode-First》一文执行过程类似。

 

cd contractfirst

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

mvn test –Pserver

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

mvn test -Pclient

 

 

 

参考内容

 

Maven中的几个重要概念()lifecycle, phase and goal

Maven生命周期详解

http://cxf.apache.org/docs/wsdl-to-java.html

http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html

http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

  • contractfirst.7z (2.7 KB)
  • 下载次数: 7

这篇关于Apache CXF开发Web Service 理解CXF Frontends之Contract-First的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/560345

相关文章

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec

基于Java开发一个极简版敏感词检测工具

《基于Java开发一个极简版敏感词检测工具》这篇文章主要为大家详细介绍了如何基于Java开发一个极简版敏感词检测工具,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录你是否还在为敏感词检测头疼一、极简版Java敏感词检测工具的3大核心优势1.1 优势1:DFA算法驱动,效率提升10

Python开发简易网络服务器的示例详解(新手入门)

《Python开发简易网络服务器的示例详解(新手入门)》网络服务器是互联网基础设施的核心组件,它本质上是一个持续运行的程序,负责监听特定端口,本文将使用Python开发一个简单的网络服务器,感兴趣的小... 目录网络服务器基础概念python内置服务器模块1. HTTP服务器模块2. Socket服务器模块

深入理解go中interface机制

《深入理解go中interface机制》本文主要介绍了深入理解go中interface机制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前言interface使用类型判断总结前言go的interface是一组method的集合,不