cxf 服务端soap报文_使用Apache CXF开发SOAP Web服务

cxf 服务端soap报文

在上一篇文章中,我逐步介绍了使用apache CXF开发简单的RESTFull服务的步骤。 在本文中,我将讨论使用CXF开发SOAP Web服务。 在继续前进之前,让我们先了解一下构成SOAP Web服务的概念/元素

SOAP或简单对象访问协议

SOAP是一种协议,用于使用诸如http,smtp等应用程序协议作为载体在网络上交换基于XML的消息。 SOAP消息包含一个SOAP信封。 信封可以分为标题和正文。 标头包含与上下文相关的定义(例如安全性),而主体包含实际的应用程序数据。 典型的SOAP消息看起来像

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header></soap:Header><soap:Body><m:GetStockPrice xmlns:m="http://www.example.org/stock"><m:StockName>IBM</m:StockName></m:GetStockPrice></soap:Body>
</soap:Envelope>

WSDL或Web服务描述语言

WSDL是基于标准的XML语言,用于描述Web服务。 WSDL完整描述了Web服务公开的公共接口,期望的参数,返回的输出结构,Web服务的位置。 WSDL将Web服务定义为能够交换消息的通信端点的集合。 这些通信端点称为端口。 端口由两部分组成。

  1. 包含Web服务公开的公共接口。 该接口包含所有方法,调用它们所需的参数以及它们返回的响应结构。
  2. 第二部分将公共接口绑定到诸如http之类的网络协议。 绑定包括诸如公共接口的位置和服务的消息格式之类的信息。

SOAP通讯样式

存在两种类型的沟通方式

  1. 文件
  2. RPC

SOAP Web服务使用的通信样式在其WSDL中定义。

在文档样式中,作为肥皂主体一部分的应用程序数据作为XML文档发送。 可以通过也是WSDL一部分的xml模式完全验证该文档。 由于XML可以按照服务开发人员的意愿包含结构,因此,对XML有效负载进行编组和解组的责任在于提供者和使用者代码的末尾。

顾名思义,以RPC风格表示,使用者调用服务方法就像调用本地方法一样。 为此,RPC消息由使用者可以调用的公共接口方法列表组成。 这些方法按名称列为xml元素。 这些方法所需的方法参数构成方法元素的子元素。 封送/取消封送的责任在于Web服务框架。 该框架包含其自己的封送/解封库。 RPC样式导致应用程序代码和Web服务框架之间的代码紧密耦合,因此规范是创建文档样式服务。 掌握了关键概念之后,让我们看一下如何使用Apache CXF编写肥皂网络服务的示例。

获取本教程的源代码

我已经在SVN中提交了本教程的源文件。

  • 您可以从以下网站下载该Web应用程序: http : //subversion.assembla.com/svn/weblog4j/Weblog4jDemo/trunk
  • 您可以从以下 网址 下载客户端: http : //subversion.assembla.com/svn/weblog4j/DemoClient/trunk

注意:这两个都是ItelliJ maven项目,因此您可以将它们直接导入到intelliJ IDE或手动将文件复制到其他IDE

创建一个struts2框架应用程序以包含您的服务。

您可以使用任何MVC框架,但出于自己的原因,我更喜欢struts2。 您可以在此处看到有关如何使用Eclipse在eclipse中创建空的struts2应用程序的示例。

添加CXF依赖项

在您的项目POM中添加以下依赖项以下载CXF jar

<properties><cxf.version>2.5.0</cxf.version>
</properties>
<dependencies><!-- apache cxf --><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-frontend-jaxrs</artifactId><version>${cxf.version}</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>${cxf.version}</version></dependency>
</dependencies>

例如,让我们创建一个简单的书架网络服务。 为简单起见,让我们假设以下用例。

  1. 在自己的书中插入一本书
  2. 从书架上按标题检索一本书。

开发服务

可以通过两种方式完成:“代码优先”和“合同优先”。 我们将使用代码优先方法。

创建服务端点接口(SEI)

让我们创建一个名为BookShelfService的SEI接口

package com.aranin.weblog4j.services;import com.aranin.weblog4j.vo.BookVO;import javax.jws.WebMethod;
import javax.jws.WebService;@WebService
public interface BookShelfService {@WebMethodpublic  String insertBook(BookVO bookVO);@WebMethodpublic  BookVO getBook(String title);
}

如果看上面的SEI,可以看出它是一个普通的Java接口,但有两个注释

  • @WebService –这是一个注释JAXWS库。 它将普通的POJO转换为Web服务。 在我们的例子中,注释位于接口定义的正上方,它通知BookShelfService不是普通接口,而是Web服务接口或SEI。 该注释还有其他一些属性可以完全定义Web服务,但是我们现在不会使用它。
  • @WebMethod –此注释是可选的,主要用于为wsdl中的公共方法提供名称属性。

实施服务。

现在我们有了SEI,因此让我们在BookShelfServiceImpl的接口中实现方法

package com.aranin.weblog4j.services;import com.aranin.weblog4j.hashdb.HashDB;
import com.aranin.weblog4j.vo.BookVO;import javax.jws.WebService;@WebService(endpointInterface = "com.aranin.weblog4j.services.BookShelfService",serviceName="bookShelfService")
public class BookShelfServiceImpl implements BookShelfService {public String insertBook(BookVO bookVO) {HashDB.insertBook(bookVO);return "Book with name : " + bookVO.getBookName() + " is now available on the shelf";  //To change body of implemented methods use File | Settings | File Templates.}public BookVO getBook(String title) {return HashDB.getBook(title);  //To change body of implemented methods use File | Settings | File Templates.}
}

此类是实现SEI的简单POJO。 这里唯一值得注意的是@WebService批注。 如果您仔细看一下,我们提供了它实现的SEI的完全合格的类名和Web服务的名称。

数据绑定类(BookVO)

package com.aranin.weblog4j.vo;import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;@XmlRootElement(name = "Book")
public class BookVO implements Serializable {private long bookId;private String bookName;private String author;public long getBookId() {return bookId;}public void setBookId(long bucketId) {this.bookId = bookId;}public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}
}

这里唯一要注意的是@XmlRootElement批注。 该注释是JAXB库的一部分。 CXF使用JAXB作为默认数据绑定组件。 由于BookVO需要在Web服务调用期间作为XML进行传输,因此需要在CXF安装中由JAXB引擎进行编组/解组。 使用@XmlRootElement批注,我们可以帮助JAXB将BookVO类映射到一个XML,该XML的name属性作为xml的根元素。

基于Spring的服务器Bean

使CXF成为Web服务框架的第一选择的原因是它通过基于Spring的配置文件发布其服务端点。 让我们创建一个配置文件并在其中注册我们的服务。 我们将文件命名为beans.xml并将其保存在应用程序的WEB-INF文件夹中

<?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"xmlns:jaxrs="http://cxf.apache.org/jaxrs"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://cxf.apache.org/jaxrshttp://cxf.apache.org/schemas/jaxrs.xsdhttp://cxf.apache.org/jaxwshttp://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:endpointid="bookShelfService"implementor="com.aranin.weblog4j.services.BookShelfServiceImpl"address="/bookshelfservice" /></beans>

现在要加载beans.xml,我们只需在web.xml中添加以下内容

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

最后,我们需要通过web.xml连接spring和CXF。

<servlet><servlet-name>CXFServlet</servlet-name><display-name>CXF Servlet</display-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class><load-on-startup>2</load-on-startup>
</servlet><servlet-mapping><servlet-name>CXFServlet</servlet-name><url-pattern>/*</url-pattern>
</servlet-mapping>

注意:我没有包括Spring ContextLoaderListner的加载。 如果您使用struts2入门原型通过maven创建了struts2应用程序,那么spring将由maven项目本身下载并注册。

现在您的Web服务已准备就绪。 在任何servlet容器中编译和部署应用程序。 如果一切都很好,那么您可以在以下位置看到您的wsld: http:// localhost:8080 / weblog4jdemo / bookshelfservice?wsdl

创建您的客户

有许多工具可用于使用wsdl生成客户端代码。 为了节省您的麻烦,我们将利用CXF自己的前端api。 因此,让我们看一下步骤。

  1. 使用您选择的IDE创建一个简单的Maven项目。 我目前正在使用IntelliJ,它很棒。 可以说该项目的名称为DemoClient。
  2. 如创建框架应用程序部分所示,添加CXF依赖项。
  3. 既然我们知道了SEI和公共方法以及绑定对象是什么。 我们将在客户端创建它们,以免给我们带来麻烦。 如果有很多这样的类,我们可以使用诸如wsdl2java之类的工具来生成我们的代码。
  4. 以与父SEI完全相同的包结构创建存根SEI。
  5. 以与父BookVO相同的包结构创建BookVO。
  6. 以上类应与您在父应用程序中创建的类完全相同。
  7. 我们不需要在客户端创建SEI实现。
  8. 现在,我们将使用JaxWsProxyFactoryBean创建一个客户端。 此类是与SEI代理一起使用以调用Web服务方法的工厂。 这是课程。
package com.aranin.weblog4j.client;import com.aranin.weblog4j.services.BookShelfService;
import com.aranin.weblog4j.vo.BookVO;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;public class DemoClient {public static void main(String[] args){String serviceUrl = "http://localhost:8080/weblog4jdemo/bookshelfservice";JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();factory.setServiceClass(BookShelfService.class);factory.setAddress(serviceUrl);BookShelfService bookService = (BookShelfService) factory.create();//insert bookBookVO bookVO = new BookVO();bookVO.setAuthor("Issac Asimov");bookVO.setBookName("Foundation and Earth");String result = bookService.insertBook(bookVO);System.out.println("result : " + result);bookVO = new BookVO();bookVO.setAuthor("Issac Asimov");bookVO.setBookName("Foundation and Empire");result = bookService.insertBook(bookVO);System.out.println("result : " + result);bookVO = new BookVO();bookVO.setAuthor("Arthur C Clarke");bookVO.setBookName("Rama Revealed");result = bookService.insertBook(bookVO);System.out.println("result : " + result);//retrieve bookbookVO = bookService.getBook("Foundation and Earth");System.out.println("book name : " + bookVO.getBookName());System.out.println("book author : " + bookVO.getAuthor());}
}

这是上述调用的输出

INFO: Creating Service {http://services.weblog4j.aranin.com/}BookShelfServiceService from class com.aranin.weblog4j.services.BookShelfService
result : Book with name : Foundation and Earth is now available on the shelf
result : Book with name : Foundation and Empire is now available on the shelf
result : Book with name : Rama Revealed is now available on the shelf
book name : Foundation and Earth
book author : Issac AsimovProcess finished with exit code 0

您可以在Apache CXF中探索大量其他内容,例如创建动态客户端,拦截器,利用其他传输协议,基于https的Web服务等。但是,我打算将本文作为入门教程。

ew,这又是一个漫长的帖子。 我需要提高写作技巧以缩短篇幅。 但我仍然希望您喜欢它并发现它有用。 我打算在我的下一篇文章中介绍有关Web服务的javascript客户端。 在那之前,再见,快乐的编码。

参考: Weblog4j博客上的JCG合作伙伴 Niraj Singh 使用Apache CXF开发SOAP Web服务 。

翻译自: https://www.javacodegeeks.com/2013/06/developing-soap-web-service-using-apache-cxf.html

cxf 服务端soap报文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/348060.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 8日期和时间

如今&#xff0c;一些应用程序仍在使用java.util.Date和java.util.Calendar API&#xff0c;包括使我们的生活更轻松地使用这些类型的库&#xff0c;例如JodaTime。 但是&#xff0c;Java 8引入了新的API来处理日期和时间&#xff0c;这使我们可以对日期和时间表示进行更精细的…

php mysql 随机字符串_MySQL_Mysql 自定义随机字符串的实现方法,前几天在开发一个系统,需要 - phpStudy...

Mysql 自定义随机字符串的实现方法前几天在开发一个系统&#xff0c;需要用到随机字符串&#xff0c;但是mysql的库函数有没有直接提供&#xff0c;就简单的利用现有的函数东拼西凑出随机字符串来.下面简单的说下实现当时.1.简单粗暴.select ..., substring(MD5(RAND()),floor(…

python哪些类型可以作为迭代器_python0.8-----set类型与迭代器

set:类似dict&#xff0c;是一组dict的集合&#xff0c;不存储value。本质&#xff1a;无序(没有下标)无重复的元素的集合。创建&#xff1a;创建set需要一个list或者tuple或者dict作为输入集合。重复元素在色中会被自动过滤。s1[1,2,3,4,5,6,1,2]set(s1){1,2,3,4,5,6} --表示》…

线程池实现填充短信_填充一个池需要多少个线程?

线程池实现填充短信在最近几个月中&#xff0c;我们一直看到很小但持续的操作失败&#xff0c;但有一个奇怪的异常– org.springframework.jdbc.CannotGetJdbcConnectionException –“无法获得JDBC连接&#xff1b; 嵌套异常是java.sql.SQLException&#xff1a;客户端尝试检出…

python线性回归x可以数量不一样吗_R和Python中的线性回归 - 在同一问题上的结果不同...

只是指出这一点&#xff1a; statsmodel s least squares fit does by default not include a constant. If we remove the constant from R适合&#xff0c;我们得到与Python实现非常相似的结果&#xff0c;或者相反&#xff0c;如果我们向 statsmodel -fit添加一个常量&#…

PostgreSQL开放自由

Open Liberty是源自WebSphere Liberty的有趣的新型OSS Java EE应用服务器。 您可以将Open Liberty配置为使用PostgreSQL作为其默认数据源&#xff0c;如下所示&#xff1a; 将<datasource> &#xff0c; <jdbcDriver>和<library>指令添加到server.xml配置中…

实现mysql百度式查询_mysql查询优化建议(百度)

1.对查询进行优化&#xff0c;应尽量避免全表扫描&#xff0c;首先应考虑在 where 及 order by 涉及的列上建立索引。2.应尽量避免在 where 子句中使用!或<>操作符&#xff0c;否则将引擎放弃使用索引而进行全表扫描。3.应尽量避免在 where 子句中对字段进行 null 值判断…

海思芯片怎么使用tde给qt加速_3519移植Qt适配附件

【实例简介】修改Qt5.5.1linuxfb插件代码&#xff0c;适配海思3519平台【实例截图】【核心代码】3519Qt移植.tar├── 3519Qt绉绘│ ├── linuxfb│ │ ├── include│ │ │ ├── acodec.h│ │ │ ├── fisheye_calibrate.h│ │ │ ├─…

jsf标签_多个动态包含一个JSF标签

jsf标签每个JSF开发人员都知道ui&#xff1a;include和ui&#xff1a;param标签。 您可以包括一个facelet&#xff08;XHTML文件&#xff09;并传递一个对象&#xff0c;该对象将在包含的facelet中可用&#xff0c;如下所示&#xff1a; <ui:include src"/sections/co…

用Java比较文件

我正在为PACKT创建一系列有关Java网络编程的视频教程。 有整节关于Java NIO。 一个示例程序是通过原始套接字连接将文件从客户端复制到服务器。 客户端从磁盘读取文件&#xff0c;服务器将到达的字节保存到磁盘。 因为这是一个演示&#xff0c;所以服务器和客户端在同一台计算机…

java哈希_Java如何采用哈希码实现分类(以员工分配为例)

5.总程序&#xff1a;下面代码是我们获取的所有的程序代码&#xff0c;如下&#xff1a;public static void main(String[] args) {Scanner scannew Scanner(System.in);System.out.println("请输入员工姓名&#xff1a;");String namescan.nextLine();System.out.pr…

java反射的原理_java反射机制的实现原理

java反射机制的实现原理反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力。通过这种能力可以彻底的了解自身的情况为下一步的动作做准备。下面具体介绍一下java的反射机制。这里你将颠覆原来对java的理解。Java的反射机制的实现要借助于4个类&#xff1a;class&…

java linkedlist 用法_Java LinkedList addLast()用法及代码示例

Java中的java.util.LinkedList.addLast()方法用于在LinkedList的末尾插入特定元素。用法:void addLast(Object element)参数&#xff1a;此函数接受单个参数element &#xff0c;如上面的语法所示。此参数指定的元素将附加在列表的末尾。返回值&#xff1a;此方法不返回任何值。…

spring 长轮询_Spring集成文件轮询和测试

spring 长轮询我最近实施了一个小项目&#xff0c;在该项目中&#xff0c;我们必须轮询文件夹中的新文件&#xff0c;然后在文件内容上触发服务流。 Spring Integration非常适合此要求&#xff0c;因为它带有一个通道适配器 &#xff0c;该适配器可以扫描文件夹中的新文件&…

java扫描指定package注解_java获取包下被指定注解的类

方案一&#xff1a; 采用reflections 框架(此框架依赖com.google.guava)2、项目依赖org.reflectionsreflections0.9.11com.google.guavaguava21.03、实现代码//入参 要扫描的包名Reflections f new Reflections("com.ggband.netty.execute.command");//入参 目标注解…

您将在下一个项目中使用JSF吗?

上周有一篇很棒的stackoverflow博客文章&#xff0c;主题是“ JavaScript框架的残酷生命周期” 。 这篇文章是关于Javascript UI框架&#xff08;angularjs&#xff0c;angular&#xff0c;jquery和react&#xff09;的流行和流行的速度。 这篇文章的关键指标是每月关于框架的问…

java dao层 service层_dao层与service层的区别

service是业务层&#xff0c;dao是数据访问层。这个问题我也曾经考虑过学java的时候&#xff0c;都是在service里直接调用dao&#xff0c;service里面就new一个dao类对象&#xff0c;调用&#xff0c;其他有意义的事没做&#xff0c;也不明白有这个有什么用然后百度了一下我们都…

java heapsort_排序算法笔记:堆排序 HeapSort in java

/*** 堆排序* 简述:* 首先使用建立最大堆的算法建立好最大堆&#xff0c;然后将堆顶元素(最大值)与最后一个值交换&#xff0c;同时使得堆的长度减小1 &#xff0c;调用保持最大堆性质的算法调整&#xff0c;使得堆顶元素成为最大值&#xff0c;此时最后一个元素已被排除在外* …

从Java 10中删除的API

在博客文章“ JDK 10 Release Candidate Phase ”中&#xff0c;我研究了JDK 10可能包含的十二个新功能。 在本文中&#xff0c;我介绍了一些可能会在JDK 10中删除的API&#xff0c;并探讨了一些在JDK 10中建议弃用的API。本文中的信息基于当前版本&#xff08;2018/1 / “ Jav…

使用java自带的日志管理_java日志管理

1.相关概念日志统一框架(日志门面)&#xff1a;apache commons logging、slf4j日志实现框架(实现层)&#xff1a;JDK自带的logging(java.util.logging)、log4j、Java Util Logging、log4j2、logback.(1)JDK自带的logging(java.util.logging)用法&#xff1a;1 importjava.util.…