WebSphere Application Server(WAS)8.5.5教程第十三讲:JMS

一、JMS

JMS(Java Message Service)是 Java 平台中的一种消息通信标准,它允许应用程序之间通过消息进行异步通信,是 企业级集成和松耦合架构中常用的技术。

1、JMS 的核心概念

1. 消息模型

JMS 定义了两种消息模型:

(1)点对点(Point-to-Point, P2P)
  • 使用 Queue(队列) 实现消息传递。

  • 特点:

    • 一个消息只能被一个消费者接收。

    • 有发送者(Sender)、接收者(Receiver)、队列(Queue)。

    • 常用于任务分发,如打印任务、订单处理队列等。

(2)发布/订阅(Publish/Subscribe, Pub/Sub)
  • 使用 Topic(主题)

  • 特点:

    • 一个消息可以被多个订阅者接收。

    • 有发布者(Publisher)、订阅者(Subscriber)、主题(Topic)。

    • 常用于广播通知,如股票行情、新闻推送等。

2. JMS 元素

元素说明
ConnectionFactory创建连接对象的工厂,WAS 中由管理员配置
Destination消息目的地,Queue 或 Topic
Connection与消息服务器的连接
Session通过连接创建的会话,线程不安全,一般每个线程一个
MessageProducer消息发送者,用于发送消息
MessageConsumer消息接收者
Message消息对象,如 TextMessage、ObjectMessage、MapMessage 等

2、JMS 消息类型

类型用途说明
TextMessage发送字符串消息(如 JSON、XML)
ObjectMessage发送 Java 序列化对象
BytesMessage发送字节流
MapMessage键值对形式的数据结构
StreamMessage基于数据流的消息

3、JMS 与 WebSphere Application Server(WAS)的关系

WAS 内置对 JMS 的支持,允许配置和管理消息服务器、队列、主题等,主要用于:

  • 企业应用异步解耦

  • 消息驱动 Bean(MDB)处理异步逻辑

  • 和 WebSphere MQ、ActiveMQ、SIB 等整合

在 WAS 中配置 JMS:

路径:资源 → JMS → 队列连接工厂 / 队列 / 主题 / 激活规范

配置步骤:

  1. 创建连接工厂(Connection Factory)

  2. 创建目标(Queue 或 Topic)

  3. 创建激活规范(用于 MDB)

  4. 绑定 JNDI 名称,供应用查找使用

4、JMS 编程模型(Java 代码示例)

Context ctx = new InitialContext();
ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jms/ConnectionFactory");
Queue queue = (Queue) ctx.lookup("jms/Queue");

Connection conn = factory.createConnection();
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(queue);

TextMessage message = session.createTextMessage("Hello JMS!");
producer.send(message);

5、与 IBM BAW 的整合

IBM BAW 通过 Service Integration Bus (SIBus) 内部集成了 JMS 实现,可以让流程或服务异步:

  • 发送消息给外部系统(如调用 MQ)

  • 监听消息队列并启动流程

  • 与 MDB 协同处理业务逻辑

BAW 中相关的集成点有:

  • 异步消息发送服务

  • JMS 触发器

  • SIB 消息引擎配置

6、JMS 应用场景

场景说明
订单处理异步入库系统接收订单立即返回响应,入库任务通过 JMS 异步处理
系统日志异步写入系统日志通过 JMS 分发给日志服务处理
支付系统通知支付完成消息发送到多个系统(发货、积分、短信)
消息驱动工作流触发外部系统将消息发到 BAW 队列,由流程自动处理

7、与 Kafka 的比较

特性JMS(如 MQ、ActiveMQ)Kafka
标准Java EE 标准Kafka 专有
消息模型P2P 和 Pub/Sub类似 Pub/Sub
持久性高(基于日志存储)
性能极高
事务支持较弱(需单独设置)
应用场景企业应用、流程驱动大数据、日志收集、实时分析

好的,我们继续深入讲解 JMS,重点在实际 WAS 配置 + Java 应用使用 + 和 BAW 结合的场景,分为以下几个部分:

8、JMS 在 WAS 中的配置实操示范

WAS(WebSphere Application Server)支持通过管理控制台配置 JMS 资源,通常用于集成 IBM MQ、ActiveMQ 或 WebSphere 内部的 SIB(Service Integration Bus)。下面以配置 内建 SIB JMS 队列 为例。

1. 启用服务集成总线(SIBus)

  • 进入 WAS 控制台

  • 路径:服务集成 > 总线 > 创建

    • 名称:SIBBus1

    • 保持默认设置

 

2. 创建消息引擎

  • 路径:服务集成 > 总线 > SIBBus1 > 代理(Messaging Engine)

    • 添加一个代理,选择你的节点

    • 选择持久化消息存储位置(文件系统或数据库)

3. 创建 JMS 目的地

  • 路径:资源 > JMS > 队列

    • 队列名称:MyQueue

    • JNDI 名称:jms/MyQueue

    • 关联 SIB 总线和消息引擎

 

4. 创建 JMS 连接工厂

  • 路径:资源 > JMS > 队列连接工厂

    • 名称:MyQueueCF

    • JNDI 名称:jms/MyQueueCF

    • 选择同一个总线

 

5. 创建激活规范(用于 MDB)

  • 路径:资源 > JMS > 激活规范

    • 名称:MyQueueAS

    • JNDI 名称:eis/MyQueueAS

    • 选择 SIB 总线和队列

 

9、Java 应用中使用 JMS(示例代码)

使用 WAS 中的资源,我们可以在 Java EE 或 Spring 应用中使用 JMS 发送和接收消息。

1. 发送消息

@Resource(name = "jms/MyQueueCF")
private ConnectionFactory connectionFactory;

@Resource(name = "jms/MyQueue")
private Queue queue;

public void sendMessage(String msgContent) {
    try (Connection conn = connectionFactory.createConnection();
         Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageProducer producer = session.createProducer(queue)) {

        TextMessage msg = session.createTextMessage(msgContent);
        producer.send(msg);
    } catch (JMSException e) {
        e.printStackTrace();
    }
}

2. 接收消息(同步方式)

public void receiveMessage() {
    try (Connection conn = connectionFactory.createConnection();
         Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageConsumer consumer = session.createConsumer(queue)) {

        conn.start();
        Message message = consumer.receive(10000); // 10秒超时

        if (message instanceof TextMessage) {
            System.out.println("Received: " + ((TextMessage) message).getText());
        }
    } catch (JMSException e) {
        e.printStackTrace();
    }
}

10、结合 BAW 使用 JMS 的方式

场景 1:BAW 流程结束时发送 JMS 消息

  • 在 BAW 的集成服务中使用 Java 组件Web Service 调用上面的消息发送逻辑

  • 示例用途:流程结束后发送消息通知财务系统入账

场景 2:通过 JMS 触发 BAW 流程

  • 在 WAS 中配置 MDB(Message-Driven Bean)监听队列

  • 接收到消息后调用 BAW REST API 启动流程或处理任务

11、集成建议与注意事项

建议说明
推荐使用 JNDI 绑定避免硬编码队列名称与工厂名称
启用持久化存储防止消息丢失
使用 MDB 消费保证异步高并发处理能力
配置死信队列捕捉处理失败的消息
开启连接池提高性能(WAS 中默认启用)

12、补充:JMS 与 Spring Boot 集成

如果你使用的是 Spring Boot + WAS/JMS,可以通过如下方式配置:

spring:
  jms:
    jndi-name: java:comp/env/jms/MyQueueCF

使用 Spring JmsTemplate:

@Autowired
private JmsTemplate jmsTemplate;

public void send(String message) {
    jmsTemplate.convertAndSend("jms/MyQueue", message);
}

二、BAW 调用 JMS 的集成流程样例

下面是一个完整的 IBM BAW 调用 JMS 的集成流程样例,包括:

  • BAW 流程建模

  • WAS 中 JMS 配置

  • Java 服务集成实现

  • 流程与服务的连接

  • 测试和验证方法

1、业务场景描述

流程名称:发送消息流程(SendJMSMessageProcess)

目标:业务流程中调用一个 Java 集成服务,向指定 JMS 队列发送消息,消息将由下游系统消费。

2、WAS 中配置 JMS(使用内建 SIB)

1. 创建服务集成总线(SIB)

  • 控制台路径:服务集成 > 总线 > 新建

    • 名称:BAWBus

2. 创建消息引擎(消息代理)

  • 绑定节点/服务器,用于运行 SIBus 代理

3. 创建队列目的地

  • 控制台路径:资源 > JMS > 队列

    • 队列名称:MyQueue

    • JNDI:jms/MyQueue

    • 指定 SIBus、代理名称

4. 创建连接工厂

  • 路径:资源 > JMS > 队列连接工厂

    • 名称:MyQueueCF

    • JNDI:jms/MyQueueCF

    • 同样绑定 SIBus

3、开发 Java 集成服务(调用 JMS)

1. Java 代码(Maven 项目)

import javax.annotation.Resource;
import javax.jms.*;
import javax.naming.InitialContext;

public class JMSSender {
    @Resource(name = "jms/MyQueueCF")
    private ConnectionFactory connectionFactory;

    @Resource(name = "jms/MyQueue")
    private Queue queue;

    public void sendMessage(String content) throws Exception {
        try (Connection connection = connectionFactory.createConnection();
             Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)) {

            MessageProducer producer = session.createProducer(queue);
            TextMessage message = session.createTextMessage(content);
            producer.send(message);
        }
    }
}

打包成 JAR 后部署到 BAW 支持的 classpath(例如共享库),或者封装为 EJB/JAX 服务。

4、BAW 中配置服务并建模

1. 在 Process Designer 中创建服务

  • 类型:集成服务(Java Integration Service)

  • 输入参数:messageContent(String)

  • 实现方式:调用 JMSSender.sendMessage(messageContent)

2. 创建业务流程

  • 添加一个用户任务输入参数

  • 调用上述集成服务节点发送消息

  • 添加结束事件

3. 配置绑定与依赖

  • 确保 WAS 的 classloader 包含 JMS Java 逻辑类

  • BAW 配置服务绑定至 JNDI 名称(WAS 控制台设置或 Server.xml)

5、测试方案

方法 1:在 BAW 流程中输入一条消息 → 队列中收到消息

  • 使用 BAW Process Portal 启动流程,输入消息文本

  • 使用 JMS 客户端(如 WebSphere MQ Explorer)监听队列

方法 2:配置 MDB 消费并打印日志

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/MyQueue"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class MessageConsumerMDB implements MessageListener {
    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            try {
                System.out.println("Received: " + ((TextMessage) message).getText());
            } catch (JMSException e) { e.printStackTrace(); }
        }
    }
}

6、部署与验证说明文档(概要)

步骤内容
第一步在 WAS 创建 SIB、队列、工厂资源
第二步编写 Java 类并部署至共享库或包装成 EJB
第三步在 BAW 创建集成服务并建模流程
第四步使用 Process Portal 发起流程测试
第五步验证队列中是否收到消息,或通过 MDB 输出日志

7、BPMN 流程模板

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
             xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
             xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
             xmlns:tns="http://example.com/bpmn"
             targetNamespace="http://example.com/bpmn">

  <process id="SendJMSMessageProcess" name="发送JMS消息流程" isExecutable="true">

    <startEvent id="StartEvent_1" name="开始"/>

    <userTask id="UserTask_Input" name="输入消息内容">
      <incoming>Flow_1</incoming>
      <outgoing>Flow_2</outgoing>
    </userTask>

    <sequenceFlow id="Flow_1" sourceRef="StartEvent_1" targetRef="UserTask_Input"/>

    <serviceTask id="ServiceTask_SendJMS" name="发送JMS消息">
      <extensionElements>
        <!-- 实现细节,如Java实现类绑定或调用的集成服务名 -->
      </extensionElements>
      <incoming>Flow_2</incoming>
      <outgoing>Flow_3</outgoing>
    </serviceTask>

    <sequenceFlow id="Flow_2" sourceRef="UserTask_Input" targetRef="ServiceTask_SendJMS"/>

    <endEvent id="EndEvent_1" name="结束"/>

    <sequenceFlow id="Flow_3" sourceRef="ServiceTask_SendJMS" targetRef="EndEvent_1"/>

  </process>

  <bpmndi:BPMNDiagram id="BPMNDiagram_SendJMS">
    <bpmndi:BPMNPlane id="BPMNPlane_SendJMS" bpmnElement="SendJMSMessageProcess">
      <!-- 图形布局信息略,可由 BAW Process Designer 自动生成 -->
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>

</definitions>

上面是一个基础的 BPMN 流程模板,名为 发送JMS消息流程(SendJMSMessageProcess)。该流程包括:

  • 开始事件

  • 用户任务:输入消息内容

  • 服务任务:发送 JMS 消息(将绑定集成服务)

  • 结束事件

你可以将该模板导入 IBM BAW Process Designer(或转换为 .twx 文件进行导入)。

三、BAW中调用JMS服务并推送审批提醒至企业微信示例

1、场景说明

在企业的流程自动化系统中,审批流程的每个节点希望在完成后自动发送审批通知至企业微信(或其他 IM 工具),提醒下一个处理人或相关人员。此通知通过 JMS 中间件推送到消息服务网关,然后转发到企业微信。

2、流程模型设计(BPMN)

流程名SendJMSMessageProcess
核心结构

  1. 开始节点(Start)

  2. 用户任务(User Task: 填写审批信息)

  3. 系统服务任务(Service Task: 调用 JMS 推送消息)

  4. 结束节点(End)

3、输入输出变量配置(流程级)

在 BAW 的流程设计器中,为流程添加以下变量:

变量名类型用途输入/输出
messageContentString审批通知消息内容输入
jmsStatusStringJMS 推送成功/失败的状态输出

4、服务绑定(服务任务)

服务任务名称:Send JMS to WeChat

服务类型:
  • 类型:集成服务

  • 实现方式:调用 Java 组件或 Java 集成服务

接口参数定义:
参数名类型方向
messageContentString输入
jmsStatusString输出
绑定服务实现(方法 1:Java 组件):

假设已创建 Java 类:

package com.example.jms;

import javax.jms.*;
import javax.naming.*;

public class WeChatJMSPublisher {
    public String sendMessage(String messageContent) throws Exception {
        InitialContext ctx = new InitialContext();
        QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("jms/WeChatConnectionFactory");
        Queue queue = (Queue) ctx.lookup("jms/WeChatQueue");

        QueueConnection conn = factory.createQueueConnection();
        QueueSession session = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
        QueueSender sender = session.createSender(queue);

        TextMessage message = session.createTextMessage();
        message.setText(messageContent);
        sender.send(message);

        sender.close();
        session.close();
        conn.close();

        return "SUCCESS";
    }
}

绑定方法可通过 Java 集成服务或 EJB 服务引用该类。 

5、WAS JMS 配置说明

1.JMS 连接工厂

  • 名称:jms/WeChatConnectionFactory

  • 类型:QueueConnectionFactory

  • 提供者类型:默认 SIBus 或外部 MQ 提供者

2.目标目的地(Destination)

  • 名称:jms/WeChatQueue

  • 类型:Queue

3.JNDI 映射:确保在 WAS 中配置了 JNDI 名称和绑定。

6、企业微信 Webhook 示例

发送格式为:

{
  "msgtype": "text",
  "text": {
    "content": "【审批提醒】张三已完成任务:请李四审批。"
  }
}

 如果 JMS 后端是一个支持 HTTP 网关服务(如 Spring Boot + Webhook 转发),则可按如下方式进行后续推送。

7、流程使用示例

用户在用户任务节点填写如下信息:

  • 审批内容:任务123审批通过,请处理下一个步骤。

提交后进入服务任务节点,调用 JMS 发送内容到 jms/WeChatQueue,由监听器转发至微信。

8、错误处理建议

  • 在服务任务中加入错误路径(例如 JMS 发送失败,走报警流程)

  • 添加 try-catch 环绕服务逻辑

  • 可在 jmsStatus 输出结果中返回错误详情

9、可选增强功能

  1. 节点后自动触发消息通知(监听流程变量变化)

  2. 消息内容模板化(结合业务数据与审批路径)

  3. 支持多平台提醒(微信、钉钉、邮件等)

  4. 异步推送与失败重试机制

10、完整示例

以下是一个完整的示例,包括:

  • Java JMS 消息发送类代码

  • IBM BAW 集成方式

  • 如何将该 Java 类导入 BAW(手动导入)

  • 消息示例及企业微信推送结构

1.Java JMS 消息发送类代码(独立组件)

你可以将以下代码打成 .jar 包导入到 BAW:

package com.example.jms;

import javax.jms.*;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class WeChatJMSPublisher {

    public String sendMessage(String messageContent) {
        try {
            InitialContext ctx = new InitialContext();

            // JNDI 名称需与你在 WAS 中配置的保持一致
            QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("jms/WeChatConnectionFactory");
            Queue queue = (Queue) ctx.lookup("jms/WeChatQueue");

            QueueConnection conn = factory.createQueueConnection();
            QueueSession session = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            QueueSender sender = session.createSender(queue);

            TextMessage message = session.createTextMessage();
            message.setText(messageContent);
            sender.send(message);

            sender.close();
            session.close();
            conn.close();

            return "SUCCESS";

        } catch (NamingException | JMSException e) {
            e.printStackTrace();
            return "FAIL: " + e.getMessage();
        }
    }
}

2.打包为 .jar 文件(步骤)

使用命令行打包:
  1. 将上面代码保存为 WeChatJMSPublisher.java,放入文件夹路径:

    src/com/example/jms/WeChatJMSPublisher.java
    
  2. 编译:

    javac -d out src/com/example/jms/WeChatJMSPublisher.java
    
  3. 打包为 JAR:

    jar cf WeChatJMSPublisher.jar -C out .
    

3.导入到 IBM BAW 环境中

1. 上传到 Process App 的 “实现” 目录:
  • 打开 BAW Process Designer

  • 在左侧导航栏中点击 “实现”

  • 选择 “外部实现” → “添加”

  • 上传 WeChatJMSPublisher.jar

2. 创建 Java 集成服务:
  • 类型:Java 集成服务

  • 类名:com.example.jms.WeChatJMSPublisher

  • 方法名:sendMessage

  • 输入参数:String messageContent

  • 输出参数:String,作为 jmsStatus 返回

4.在流程中使用该服务

  1. 创建一个服务任务,绑定上面 Java 集成服务。

  2. 配置输入变量 messageContent,如:

    【审批通知】用户 张三 已完成审批任务,请 李四 查看。
    
  3. 将输出绑定到变量 jmsStatus,用于记录状态或走错误路径。

5.企业微信接收端建议设计

若你使用一个 HTTP Gateway 转发 JMS 消息至微信:

示例 Java 后端监听器(Spring):
@RestController
@RequestMapping("/jms/wechat")
public class WeChatReceiverController {

    @PostMapping("/push")
    public ResponseEntity<?> pushToWeChat(@RequestBody String message) {
        // 调用企业微信 Webhook 推送
        String webhook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxx";

        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> payload = new HashMap<>();
        payload.put("msgtype", "text");
        Map<String, String> text = new HashMap<>();
        text.put("content", message);
        payload.put("text", text);

        ResponseEntity<String> response = restTemplate.postForEntity(webhook, payload, String.class);
        return ResponseEntity.ok("Pushed to WeChat: " + response.getBody());
    }
}

6.调试建议

  • 在 WAS 控制台中启用 JMS Trace 级别日志。

  • BAW 中流程服务任务绑定异常路径用于捕获错误。

  • 使用 Service Integration Bus 控制台监控消息流动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深海科技服务

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值