WS-Notification的使用---来自阿红
JAX-WS:
SOAP 栈 和 XML marshaling
ServiceMix使用JAX-WS和JAXB 2.0来创建WS-*规范的POJO、接口,例如WS-Addressing, WS-Notification, WS-ReliableMessaging, WS-Resourceframework等等。这种方法的唯一缺点是Java5特定的,因此不能在JDK1.5以下的JVM运行。要使用JDK1.4 JVM,或者使用XMLBeans,或者使用Retroweaver之类的工具来把JDK1.5实现转换为JDK1.4二进制。
WS-Notification
WS-Notification支持当前的实现是POJO,可以直接在应用中调用,也可以打包为远程的Web服务(使用遵从JAX-WS约束的SOAP协议栈来访问)。当前使用JAX WS RI(参考实现)
WS-Notification的接口在org. servicemix.wspojo.notification 包中,由JAX-WS从WSDL文件生成而来,依赖于JAVA5 、JAX-WS以及JAXB2.0注解。
WS-Notification的实现在WS-Notification interfaces are here.
接口的apidoc: org. servicemix.wspojo.notification
使用 WS-Notification
为了可以pub/sub,需要一个NotificationConsumer 或者 NotificationBroker。当前的实现都是ActiveMQNotificationBroker。这个Broker会创建一个到ActiveMQ代理的连接(缺省时是在同一个JVM内嵌入broker)。
Publish一个 WS-Notification消息,如下:
EndpointReferenceType consumer = createEPR(ReceiverComponent.SERVICE, ReceiverComponent.ENDPOINT);
wsnBroker.subscribe(consumer, "myTopic", null, true);
Element body = parse("<hello>world</hello>");
wsnBroker.notify("myTopic", body);
sub:
PullPoint pullPoint = wsnCreatePullPoint.createPullPoint();
Subscription subscription = wsnBroker.subscribe(pullPoint.getEndpoint(), "myTopic", null);
运行时依赖
除了ActiveMQ、ServiceMix的依赖之外,WS-Notification还依赖于:
- JAX-WS 、JAXB 2.0 APIs (annotations) 将内嵌在JAVA 6,但在JDK 5中只需添加jaxb-api.jar 以及 jaxws-api.jar
- JAX-WS 实现。如果想要支持SOAP协议上的远程服务。当前使用JAX-WS RI
ServiceMix WSIF Example
Web Services Invocation Framework (WSIF)提供了调用Web服务的Java API,隐藏服务是如何提供的细节,例如是通过SOAP、JMS还是其他什么,等等。
下面说明ServiceMix构件使用不同的实现协议,例如Axis、本地Java、EJB、JMS、JCA或者CCI,与Apache WSIF交互,来调用Web服务。
WSIF example 演示了如何通过WSIF展示Web服务(over JMS队列):
NOTE: 本实例不是一个完整的可run的例子。它只是通过一个典型实用的web应用演示了WSIF在ServiceMix构件中是怎么使用的。图中的下列构件没有完全实现:
1. Web Form没有创建
2. 没有配置servicemix.xml 中HTTP BC的目标服务为"checkAvailabity"构件.
下面给出的关键代码片断摘自一个更大的例子,可以在Apache Web Services Project中找到。本实例中,客户端应用通过JMS队列向Web服务应用提交ZIP Code。Web服务检查此ZIP Code地区的DSL服务是否可用,发送JMS队列消息回映客户。客户端使用WSIF来隐藏JMS实现细节。
在本实例中,客户端使用WSIF API向Web服务发送ZIP Code请求。WSIF为客户端处理JMS细节。ServiceMix WSIF API向客户提供统一的API,处理Web服务调用的细节,简化客户端编程。
此实例中显示了ServiceMix客户API的重要特性:如何为一个Web服务绑定包含附加的用来配置服务实现的WSIF元数据的WSDL文件。
也就是说,servicev.wsdl文件包含了WSIF对WSDL的扩展,扩展中绑定了Web服务的传输协议。
例子的详细分析
逻辑流程:
1. 用户打开Web浏览器,访问一个Web表单,输入信息后按submit按钮提交Zip Code。提交按钮发送表单和Zip Code
2. ServiceMix HTTP BC通过客户API创建一个InOut exchange message. 消息发送到NMR,随后到checkAvailability 构件
3. checkAvailability 构件发送请求到JMS队列
4. 此Web 服务使用MDB实现,它的"onMessage" 方法监听队列中的消息
5. MDB处理请求,并通过一个临时队列发送回应消息给checkAvailability构件。回应或者是‘true’,或者是‘false’
6. checkAvailability 构件从队列中收到回应消息
7. checkAvailability 构件回应 HTTP 客户
8. 客户发送结果给Web Form,显示处理结果。
程序细节
对应的servicemix.xml文件:
<component id="checkAvailability" service="foo:checkAvailability" class="org.servicemix.components.wsif.WSIFBinding">
<property name="definitionResource" value="classpath:org/servicemix/components/wsif/service.wsdl"/>
</component>
Service.wsdl:位于servicemix_src_install_dir/servicemix-components/src/test/resources/org/apache/servicemix/components/wsif
<service name='CheckServiceAvailability'>
<port name='CheckAvailabilityPort' binding='tns:CheckAvailabilityJMSBinding'>
<!-- ActiveMQ configuration -->
<jms:address destinationStyle="queue"
jndiDestinationName="dynamicQueues/test.org.servicemix.example.wsif"
jndiConnectionFactoryName="ConnectionFactory"
initialContextFactory="org.activemq.jndi.ActiveMQInitialContextFactory"
jndiProviderURL="tcp://localhost:61626"/>
</port>
</service>
<jms:address jmsVendorURI="xxx"
jndiDestinationName="xxx"
destinationStyle="xxx"
jndiConnectionFactoryName="xxx"
initialContextFactory="xxx"
jndiProviderURL="xxx"
jmsProviderDestinationName="xxx"
jmsImplementationSpecificURI="xxx" />
- port 元素中只能有一个jms:address
- jmsVendorURI 是可选元素,WSIF不使用。不过允许客户端来获取JMS实现。
- destinationStyle 、jmsImplementationSpecificURI中必须有一个元素(且仅有一个)要指明
- jmsImplementationSpecificURI 以实现特定的格式表示的队列管理器和队列.WSIF目前未实现
- destinationStyle 的值为queue 或topic, 但目前WSIF没有实现Topic。
- 若指明了destinationStyle,则jndiDestinationNamejms、ProviderDestinationName二选一地要指明其中一个.
- jndiDestinationName 是WSIF将发送请求消息的目的JMS Queue的JNDI名字
- jmsProviderDestinationName 是WSIF将发送请求消息的目的JMS Queue的JMS名字
- 若指明了jndiDestinationNamethen或jmsProviderDestinationName,则必须指定jndiConnectionFactoryName
- 当指定的是jmsProviderDestinationName名时,jndiConnectionFactoryName 有可能要使用,因为replyTo Queue的JNDI名字有可能要传到WSIF中
- jndiConnectionFactoryName是WSIF将使用的连接工厂的JNDI名字
- 若指明了destinationStyle, 则jndiProviderURL /initialContextFactory (同时或者任意一个都可以)需要指明。
- jndiProviderURL 和 initialContextFactory 指明了要使用的JNDI数据库。未指定则WSIF使用缺省的JNDI
WSIF 使用下列顺序查找JNDI中的队列和队列管理器 :
1. 在缺省的(本地)JNDI查找 java:comp/env/<name>
2. 在WSDL中指定的JNDI中查找 java:comp/env/<name>
3. 在缺省的(本地)JNDI查找 <name>
4. 在WSDL中指定的JNDI中查找 <name>
编码WSDL1.1的parts:XML vs. properties
JBI规范要求使用XML编码机制编码WSDL1.1的parts。ServiceMix支持此要求。另外,ServiceMix也支持NMR消息的消息属性,直接使用wsdl文件中的命名parts,因此避免了不必要的XML marshalling。
作为可选方案,也可以写一个Java客户而不是Web Form来调用Web服务。下列Java客户端代码使用支持WSIF方式调用的ServiceMix客户API,传入和传出命名参数。此Java客户功能类似上图中的Http Client。也需要配置来与”checkAvailablity”服务通讯,即要配置”checkAvailablity”为它的NMR消息目的地。
InOut exchange = client.createInOutExchange();
exchange.getInMessage().setProperty("zipCode", "10505");
client.sendSync(exchange);
NormalizedMessage out = exchange.getOutMessage();
String result = (String) out.getProperty("result");
System.out.println("Found value: " + result);
上述Java 代码使用WSDL 1.1 service.wsdl ,直接使用它的命名的parts:
<message name='checkAvailabilityRequest'>
<part name='zipCode' type='xsd:string'/>
</message>
<message name='checkAvailabilityResponse'>
<part name='result' type='xsd:string'/>
</message>
<portType name='CheckAvailabilityPortType'>
<operation name='checkAvailability'>
<input message='tns:checkAvailabilityRequest'/>
<output message='tns:checkAvailabilityResponse'/>
</operation>
</portType>
<binding name='CheckAvailabilityJMSBinding' type='tns:CheckAvailabilityPortType'>
<jms:binding type="TextMessage"/>
<format:typeMapping encoding="XML" style="Java">
<format:typeMap typeName="xsd:string" formatType="java.lang.String"/>
</format:typeMapping>
<operation name='checkAvailability'>
<input>
<jms:input parts="zipCode"/>
<jms:property message="Request" part="myInt"/>
<jms:propertyValue name="myLiteralString" type="xsd:string" value="Hello World"/>
</input>
<output>
<jms:output parts="result"/>
</output>
</operation>
</binding>
WebServices消息在不同的技术中的表示方法
如果通过BPEL服务引擎、JAXRPC应用等等发送JBI实现的WSDL (1.1)消息,就必须对其加以转换/调整。
如下的WSDL消息:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="urn:sample"
xmlns:tns="urn:sample"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<types>
<xsd:schema targetNamespace="urn:sample">
<xsd:element name="value" type="xsd:string" />
</xsd:schema>
</types>
<message name="sampleMessage">
<part name="part1" type="xsd:string" />
<part name="part2" element="tns:value" />
</message>
</definitions>
对应的两个消息实例:
A 在bpel2.0中:概念化地在一个独立的xml文档中实现每个WSDL消息部分(part)。在这种情况下,或者文档元素相当于一个合成元素,其类型等同于部分(part)的type属性;或者文档元素就是部分(part)的element属性本身所引用的元素。
<ns2:message xmlns:ns2="http://com.bea.sample.bpelmessage">
first value!
</ns2:message>
<ns1:value xmlns:ns1="urn:sample">second value!</ns1:value>
B JBI中
对于JBI,WSDL (1.1)消息是在一个xml文档中实现的,该文档的元素将每个消息部分“包装”为子元素。
<jbi:message version="1.0" type="ns1:sampleMessage"
xmlns:ns1="urn:sample" xmlns:jbi="...">
<jbi:part>first value!</jbi:part>
<jbi:part>
<ns1:value>second value!</ns1:value>
</jbi:part>
</jbi:message>
C JAXRPC 2.0:
JAXRPC方法稍微有点不同,因为JAXRPC将WSDL消息绑定到Java,而不是在xml文档中表示它。但是这种方法还是类似于BPEL,因为它将每个WSDL消息部分绑定到单独的Java方法参数。
在这种情况下,可以考虑稍微改动一下前面的WSDL定义,使其更适合于RPC:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="urn:sample"
xmlns:tns="urn:sample"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<types>
<xsd:schema targetNamespace="urn:sample">
<xsd:element name="value1" type="xsd:string" />
<xsd:element name="value2" type="xsd:string" />
</xsd:schema>
</types>
<message name="sampleMessage">
<part name="part1" element="tns:value1" />
<part name="part2" element="tns:value2" />
</message>
<portType name="samplePT">
<operation name="sampleOper">
<input message="tns:sampleMessage" />
</operation>
</portType>
</definitions>
对应的Java绑定如下:
void sampleOper(java.lang.String part1, java.lang.String part2)throws RemoteException
D WSDL 2.0:
WSDL 2.0是这样解决这个问题的:避开WSDL消息部分概念,使用W3CSchema元素指定WSDL消息,W3CSchema元素在实现为文档实例时就已经具有显式映射了。
WS-Notification的使用---来自阿红相关推荐
- 各位,我来自数位红公司,我们是做手机游戏的。
我们公司最近一直再找J2ME游戏开发人员,不知道这里的朋友有没有兴趣. 有兴趣可以联络我,我的E-mail: richard@worldup.com 不要兼职.工作在北京. 有关我们的介绍可以在 ww ...
- SM中两种组件的区别----来自阿红
Servicemix中有两类构件: 轻量级构件(也称为Pojo构件):实现了JBI规范中定义的构件必须实现的接口(Component和ComponentLifeCycle接口).轻量级构件不可以在运行 ...
- Kafka是什么,JMS是什么,常见的类JMS消息服务器,为什么需要消息队列(来自学习笔记)
1.Kafka是什么 Apache Kafka是一个开源消息系统,由Scala写成.是由Apache软件基金会开发的一个开源消息系统项目. Kafka最初是由LinkedIn开发,并于2011 ...
- 一文搞懂JVM架构:java二叉树和红黑树
前言 Spring已经是我们Java Web开发必不可少的一个框架,其大大简化了我们的开发,提高了开发者的效率.同时,其源码对于开发者来说也是宝藏,从中我们可以学习到非常优秀的设计思想以及优雅的命名规 ...
- 独立站如何制定网红营销策略
受疫情营销,全球社媒飞速发展,据统计,全球社交媒体用户已超过46亿,目前10个互联网用户中有9个以上每月使用社交平台,且平均每人每天在社交网络上花费2个半小时.这也使得社媒营销迅速发展,成为各大品牌的 ...
- 独立站如何制定网红营销策略?
受疫情营销,全球社媒飞速发展,据Nox聚星(NoxInfluencer)统计,全球社交媒体用户已超过46亿,目前10个互联网用户中有9个以上每月使用社交平台,且平均每人每天在社交网络上花费2个半小时. ...
- 转载:JMS-ActiveMQ浅析
ActiveMQ 即时通讯服务 浅析 一. 概述与介绍 ActiveMQ 是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ 是一个完全支持JMS1.1和J2EE ...
- 史上最全,100+大数据开源处理工具汇总
本文除了一些常用的大数据工具,还总结汇总了其他大数据工具,几乎是最全的大数据工具的总结. 如果你想入门大数据,可以对他们进行简单的了解. 如果你想学习自己熟悉意外的大数据工具,可以看这篇文章. 如果你 ...
- ActiveMQ消息队列安装和使用
ActiveMQ ActiveMQ介绍 什么是ActiveMQ ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规 ...
最新文章
- python时间函数报错_python3中datetime库,time库以及pandas中的时间函数区别与详解...
- JNDI数据库连接池的配置
- linux运维必学python吗_linux运维一定要学python吗?
- 整合mybatis——使用纯注解整合、使用Mapper+Mapper.xml整合、使用mybatis.cfg.xml整合
- JavaScript new对象的四个过程
- ioc spring 上机案例_通过实例解析Spring Ioc项目实现过程
- Maven配置项目依赖使用本地仓库的方法汇总
- 初步创建vue/cli工程教程
- apple id两步验证服务器,【安全可靠】Apple ID 两步验证支持中国地区 - 爱应用
- Python习题练习 + 简单语法总结
- MYSQL_DQL语言的学习(1)
- LOJ#6198. 谢特(SAM+01Trie树合并)
- Android应用优化之流畅度优化实操
- leetcode 1. 黑白方格画
- 腾讯云 AI 视觉产品基于流计算 Oceanus(Flink)的计费数据去重尝试
- VMware P2V 转换实验
- 【python实现网络爬虫(14)】python爬取酷狗中多类型音乐步骤详解(附全部源代码)
- Studio One6完整兼容版音频数字音乐工作站DAW
- 安卓小项目之EveryDay(6)----使用第三方平台获取短信验证码
- 领带的10种打法(男人必看)