13.2. JMS URI

概述

使用 SOAP/JMS 时,将使用 JMS URI 指定端点的目标目的地。JMS URI 也可以通过在 URI 中附加一个或多个选项来配置 JMS 连接。这些选项在 IETF 标准中详述,Java 消息服务 1.0 的 URI Scheme 进行了详细。它们可用于配置 JNDI 系统、要使用的回复目的地、要使用的交付模式和其他 JMS 属性。

语法

例 13.4 “JMS URI 选项的语法” 所示,您可以在 JMS URI 的末尾附加一个或多个选项,方法是使用问号(?)从目标地址中分离它们。多个选项由 符号(和)分隔例 13.4 “JMS URI 选项的语法” 演示了在 JMS URI 中使用多个选项的语法。

例 13.4. JMS URI 选项的语法

jms:variant:jmsAddress?option1=value1&option2=value2&_optionN_=valueN

JMS 属性

表 13.2 “JMS 属性设置为 URI 选项” 显示影响 JMS 传输层的 URI 选项。

表 13.2. JMS 属性设置为 URI 选项

属性默认描述

conduitIdSelectorPrefix

 

[可选] 一个字符串值,它前缀放在 conduit 所创建的所有 correlation ID 中。选择器可以使用它来侦听回复。

deliveryMode

PERSISTENT

指定是否使用 JMS PROJECTI STENTNON_PROJECTISTENT 消息语义。如果是 BASEI STENT 交付模式,JMS 代理会在确认它们前将消息存储在持久性存储中;而 NON_955ISTENT 消息仅保存在内存中。

durableSubscriptionClientID

 

[可选] 指定连接的客户端标识符。此属性用于将连接与提供程序代表客户端维护的状态关联。这可让后续具有相同身份的订阅者恢复之前订阅者留下它的状态。

durableSubscriptionName

 

[可选] 指定订阅的名称。

messageType

byte

指定 CXF 使用的 JMS 消息类型。有效值为:

  • 字节
  • text
  • 二进制(二进制)

password

 

[可选] 指定用于创建连接的密码。不建议将此属性附加到 URI。

priority

4

指定 JMS 消息优先级,范围从 0(最低)到 9(最高)。

receiveTimout

60000

指定时间(以毫秒为单位),在使用请求/回复时,客户端将等待回复。

reconnectOnException

true

[在 CXF 3.0] 中已弃用,指定传输是否应在异常时重新连接。

从 3.0 开始,当出现异常时,传输总是重新连接。

replyToName

 

[可选] 指定队列信息的回复目的地。回复目的地会出现在 JMSReplyTo 标头中。建议为具有请求性语义的应用设置此属性,因为如果未指定,JMS 提供程序将分配一个临时回复队列。

此属性的值会根据 JMS URI 中指定的变体进行解释:

  • JNDI 变体 - 由 JNDI 解析的目标队列的名称
  • 使用 JMS 解析目标队列的队列变体名称

sessionTransacted

false

指定事务类型。有效值为:

  • true- 资源本地事务
  • false-JTA 事务

timeToLive

0

指定 JMS 提供程序将丢弃消息的时间(以毫秒为单位)。值为 0 表示无限生命周期。

topicReplyToName

 

[可选] 指定主题信息的答复目的地。此属性的值会根据 JMS URI 中指定的变体进行解释:

  • JNDI-topic- 由 JNDI 解析的目标主题的名称
  • 主题- 由 JMS 解析的目标主题的名称

使用ConduitIdSelector

true

指定 conduit 的 UUID 作为所有关联 ID 的前缀。

因为所有 conduits 都被分配一个唯一 UUID,请将此属性设置为 true 可让多个端点共享 JMS 队列或主题。

username

 

[可选] 指定用来创建连接的用户名。

JNDI 属性

表 13.3 “JNDI 属性设为 URI 选项” 显示可用于为此端点配置 JNDI 的 URI 选项。

表 13.3. JNDI 属性设为 URI 选项

属性描述

jndiConnectionFactoryName

指定 JMS 连接工厂的 JNDI 名称。

jndiInitialContextFactory

指定 JNDI 提供程序的完全限定 Java 类名称(必须是 javax.jms.InitialContextFactory 类型)。等同于设置 java.naming.factory.initial Java 系统属性。

jndiTransactionManagerName

指定在 Spring、蓝图或 JNDI 中搜索的 JTA 事务管理器的名称。如果找到事务管理器,则将启用 JTA 事务。请参阅 sessionTransacted JMS 属性。

jndiURL

指定初始化 JNDI 供应商的 URL。等同于设置 java.naming.provider.url Java 系统属性。

其他 JNDI 属性

其属性 java.naming.factory.initialjava.naming.provider.url 是初始化任何 JNDI 提供者所需的标准属性。但是,除标准外,JNDI 提供程序还可能支持自定义属性。在本例中,您可以通过设置 jndi-PropertyName 格式的 URI 选项来设置任意 JNDI 属性。

例如,如果您使用 SUN 的 LDAP 实现,您可以使用 JNDI 属性 java.naming.factory.control 在 JMS URI 中,如 例 13.5 “在 JMS URI 中设置 JNDI 属性” 所示。

例 13.5. 在 JMS URI 中设置 JNDI 属性

jms:queue:FOO.BAR?jndi-java.naming.factory.control=com.sun.jndi.ldap.ResponseControlFactory

示例

如果尚未配置 JMS 提供程序,则可以使用选项在 URI 中提供先决条件 JNDI 配置详情(请参阅 表 13.3 “JNDI 属性设为 URI 选项”)。例如,若要配置端点以使用 Apache ActiveMQ JMS 提供程序并连接到名为 test.cxf.jmstransport.queue 的队列,可使用 例 13.6 “配置 JNDI 连接的 JMS URI” 中显示的 URI。

例 13.6. 配置 JNDI 连接的 JMS URI

jms:jndi:dynamicQueues/test.cxf.jmstransport.queue
?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory
&jndiConnectionFactoryName=ConnectionFactory
&jndiURL=tcp://localhost:61616

发布服务

JAX-WS 标准 publish() 方法无法用于发布 SOAP/JMS 服务。反之,您必须使用 Apache CXF 的 JaxWsServerFactoryBean 类,如 例 13.7 “发布 SOAP/JMS 服务” 所示。

例 13.7. 发布 SOAP/JMS 服务

String address = "jms:jndi:dynamicQueues/test.cxf.jmstransport.queue3"
    + "?jndiInitialContextFactory"
    + "=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
    + "&jndiConnectionFactoryName=ConnectionFactory"
    + "&jndiURL=tcp://localhost:61500";
Hello implementor = new HelloImpl();
JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(Hello.class);
svrFactory.setAddress(address);
svrFactory.setTransportId(JMSSpecConstants.SOAP_JMS_SPECIFICIATION_TRANSPORTID);
svrFactory.setServiceBean(implementor);
svrFactory.create();

例 13.7 “发布 SOAP/JMS 服务” 中的代码执行以下操作:

创建代表类端点地址的 JMS URI。

实例化 JaxWsServerFactoryBean 以发布该服务。

使用服务的 JMS URI 设置 factory bean 的 address 字段。

指定工厂创建的服务将使用 SOAP/JMS 传输。

消耗服务

标准 JAX-WS API 无法用于使用 SOAP/JMS 服务。反之,您必须使用 Apache CXF 的 JaxWsProxyFactoryBean 类,如 例 13.8 “消耗 SOAP/JMS 服务” 所示。

例 13.8. 消耗 SOAP/JMS 服务

// Java
public void invoke() throws Exception {
    String address = "jms:jndi:dynamicQueues/test.cxf.jmstransport.queue3"
        + "?jndiInitialContextFactory"
        + "=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
        + "&jndiConnectionFactoryName=ConnectionFactory&jndiURL=tcp://localhost:61500";
    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
    factory.setAddress(address);
    factory.setTransportId(JMSSpecConstants.SOAP_JMS_SPECIFICIATION_TRANSPORTID);
    factory.setServiceClass(Hello.class);
    Hello client = (Hello)factory.create();
    String reply = client.sayHi(" HI");
    System.out.println(reply);
}

例 13.8 “消耗 SOAP/JMS 服务” 中的代码执行以下操作:

创建代表类端点地址的 JMS URI。

实例化 JaxWsProxyFactoryBean 来创建代理。

使用服务的 JMS URI 设置 factory bean 的 address 字段。

指定工厂创建的代理将使用 SOAP/JMS 传输。