AEM 与 ActiveMQ 集成方案详解
一、环境准备
- AEM 环境:AEM 6.5+ 或 AEM as a Cloud Service
- ActiveMQ:版本 5.15+(推荐 5.17.x)
- Maven 项目:用于开发 AEM 组件和配置
二、ActiveMQ 配置
1. 启用 JMS 连接
conf/activemq.xml,确保支持 OpenWire 协议:<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
2. 创建 JMS 用户(可选)
conf/users.properties 添加专用用户:jmsuser=jms password,users
三、AEM 集成步骤
1. 添加 ActiveMQ 依赖
pom.xml 中添加依赖:<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>5.17.10</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
2. 创建 OSGi 配置
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.ObjectClassDefinition; @ObjectClassDefinition(name = "ActiveMQ Connection Factory Configuration")
public @interface ActiveMQConfig {
@AttributeDefinition(name = "Broker URL", description = "ActiveMQ Broker URL")
String brokerUrl() default "tcp://localhost:61616"; @AttributeDefinition(name = "Username", description = "ActiveMQ Username")
String username() default "admin"; @AttributeDefinition(name = "Password", description = "ActiveMQ Password")
String password() default "admin";
}
3. 实现 JMS 连接工厂服务
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.metatype.annotations.Designate; @Component(service = ActiveMQService.class, immediate = true)
@Designate(ocd = ActiveMQConfig.class)
public class ActiveMQService {
private ConnectionFactory connectionFactory;
private ActiveMQConfig config; @Activate
@Modified
protected void activate(ActiveMQConfig config) {
this.config = config;
initConnectionFactory();
} private void initConnectionFactory() {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(
config.username(),
config.password(),
config.brokerUrl()
);
// 配置选项(可选)
factory.setTrustAllPackages(true);
this.connectionFactory = factory;
} public ConnectionFactory getConnectionFactory() {
return connectionFactory;
}
}
4. 实现 JMS 消息生产者
import javax.jms.*;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; @Component(service = JmsMessageProducer.class)
public class JmsMessageProducer {
private static final Logger LOG = LoggerFactory.getLogger(JmsMessageProducer.class); @Reference
private ActiveMQService activeMQService; public void sendMessage(String queueName, String messageContent) {
Connection connection = null;
Session session = null;
MessageProducer producer = null; try {
ConnectionFactory factory = activeMQService.getConnectionFactory();
connection = factory.createConnection();
connection.start(); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(queueName);
producer = session.createProducer(destination); TextMessage message = session.createTextMessage(messageContent);
producer.send(message);
LOG.info("Message sent to queue: {}", queueName); } catch (JMSException e) {
LOG.error("Failed to send message", e);
} finally {
// 关闭资源
closeQuietly(producer);
closeQuietly(session);
closeQuietly(connection);
}
} private void closeQuietly(AutoCloseable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (Exception e) {
LOG.warn("Error closing resource", e);
}
}
}
}
5. 实现 JMS 消息消费者(Sling Model)
import javax.jms.*;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Model;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; @Model(adaptables = SlingHttpServletRequest.class)
public class JmsMessageConsumer {
private static final Logger LOG = LoggerFactory.getLogger(JmsMessageConsumer.class); @Reference
private ActiveMQService activeMQService; public String receiveMessage(String queueName) {
Connection connection = null;
Session session = null;
MessageConsumer consumer = null; try {
ConnectionFactory factory = activeMQService.getConnectionFactory();
connection = factory.createConnection();
connection.start(); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(queueName);
consumer = session.createConsumer(destination); // 同步接收消息(超时时间 5 秒)
Message message = consumer.receive(5000);
if (message instanceof TextMessage) {
return ((TextMessage) message).getText();
}
} catch (JMSException e) {
LOG.error("Failed to receive message", e);
} finally {
// 关闭资源
closeQuietly(consumer);
closeQuietly(session);
closeQuietly(connection);
}
return null;
} // 省略 closeQuietly 方法(同上)
}
四、AEM 组件集成示例
1. 创建 Sling Model 调用生产者
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Model;
import org.osgi.service.component.annotations.Reference; @Model(adaptables = SlingHttpServletRequest.class)
public class AemMessageSender {
@Reference
private JmsMessageProducer messageProducer; public void sendAemContent(String content) {
messageProducer.sendMessage("aem.content.queue", content);
}
}
2. 创建 HTL 模板触发消息发送
<sly data-sly-use.model="com.example.models.AemMessageSender">
<button onclick="sendContent()">Send Content to ActiveMQ</button>
<script>
function sendContent() {
fetch('/bin/sendMessage', { method: 'POST' })
.then(response => response.text())
.then(data => console.log(data));
}
</script>
</sly>
3. 创建 Sling Servlet 处理消息发送请求
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference; import javax.servlet.Servlet;
import java.io.IOException; @Component(service = Servlet.class,
property = {
"sling.servlet.paths=/bin/sendMessage",
"sling.servlet.methods=POST"
}
)
public class MessageSendServlet extends SlingAllMethodsServlet {
@Reference
private AemMessageSender messageSender; @Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
String content = request.getParameter("content");
messageSender.sendAemContent(content);
response.getWriter().write("Message sent successfully");
}
}
五、高级配置(可选)
1. 配置 JMS 持久化
activemq.xml 启用持久化:<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>
2. 配置消息监听器(异步消费)
@Component(service = MessageListener.class, immediate = true)
public class AemMessageListener implements MessageListener {
@Activate
protected void activate() {
// 初始化 JMS 连接并注册监听器
// 代码略(类似消费者实现)
} @Override
public void onMessage(Message message) {
try {
if (message instanceof TextMessage) {
String content = ((TextMessage) message).getText();
// 处理接收到的消息(如更新 AEM 内容)
processAemContent(content);
}
} catch (JMSException e) {
LOG.error("Error processing message", e);
}
} private void processAemContent(String content) {
// 实现 AEM 内容处理逻辑
}
}
六、验证集成效果
- 启动 ActiveMQ:
bin/activemq start
- 部署 AEM 包:将开发的 OSGi 组件打包部署到 AEM。
- 测试消息发送:
- 通过 AEM 页面触发消息发送
- 查看 ActiveMQ 控制台(http://localhost:8161/admin/queues.jsp)确认消息入队
- 测试消息接收:
- 实现消息消费者服务
- 验证消息是否正确处理
七、常见问题与解决方案
- 连接失败
- 检查 ActiveMQ 地址和端口
- 确认防火墙未阻止通信(默认 61616 端口)
- 消息丢失
- 确保使用
DeliveryMode.PERSISTENT - 检查 ActiveMQ 持久化配置
- 确保使用
- AEM 组件无法访问 JMS 服务
- 检查 OSGi 配置是否正确
- 确认依赖包已正确导入
AEM 与 ActiveMQ 集成方案详解的更多相关文章
- Server-U FTP与AD完美集成方案详解
最近咱有个任务,那就是把公司的文件服务器.FTP服务器.邮件服务器进行迁移并作相应的整合.登陆后台查看了,公司目前正在使用的方案.FTP服务器使用的是Server-u FTP,验证方式选择的windo ...
- 最佳实战Docker持续集成图文详解
最佳实战Docker持续集成图文详解 这是一种真正的容器级的实现,这个带来的好处,不仅仅是效率的提升,更是一种变革:开发人员第一次真正为自己的代码负责——终于可以跳过运维和测试部门,自主维护运行环境( ...
- 安卓集成发布详解(二)gradle
转自:http://frank-zhu.github.io/android/2015/06/15/android-release_app_build_gradle/ 安卓集成发布详解(二) 15 Ju ...
- 莱特币ltc在linux下的多种挖矿方案详解
莱特币ltc在linux下的多种挖矿方案详解 4.0.1 Nvidia显卡Linux驱动Nvidia全部驱动:http://www.nvidia.cn/Download/index.aspx?lang ...
- 基于rem的移动端响应式适配方案(详解) 移动端H5页面的设计稿尺寸大小规范
基于rem的移动端响应式适配方案(详解) : https://www.jb51.net/article/118067.htm 移动端H5页面的设计稿尺寸大小规范 http://www.tuyiyi.c ...
- SpringBoot系列(六)集成thymeleaf详解版
SpringBoot系列(六)集成thymeleaf详解版 1. thymeleaf简介 1. Thymeleaf是适用于Web和独立环境的现代服务器端Java模板引擎. 2. Thymeleaf ...
- App域名劫持之DNS高可用 - 开源版HttpDNS方案详解(转)
http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=209805123&idx=1&sn=ced8d67c3e2cc3 ...
- 性能百万/s:腾讯轻量级全局流控方案详解
WeTest 导读 全新的全局流控实现方案,既解决了目前流控的实现难点,同时保证运行稳定且流控准确的前提下,实现更简单,部署成本更低,容灾能力更强. 该方案组件化之后,可以推广到别的有需要的部门使用, ...
- P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解
1.内容概述 P2P即点对点通信,或称为对等联网,与传统的服务器客户端模式(如下图"P2P结构模型"所示)有着明显的区别,在即时通讯方案中应用广泛(比如IM应用中的实时音视频通信. ...
- Spring Boot 集成 FreeMarker 详解案例(十五)
一.Springboot 那些事 SpringBoot 很方便的集成 FreeMarker ,DAO 数据库操作层依旧用的是 Mybatis,本文将会一步一步到来如何集成 FreeMarker 以及配 ...
随机推荐
- 【Guava工具类】Strings&Ints
String相关工具 Strings Guava 提供了一系列用于字符串处理的工具: 对字符串为null或空的处理 nullToEmpty(@Nullable String string):如果非空, ...
- llamacpp转换hf、vllm运行gguf
Linux通过huggingface安装大模型 huggingface官网 https://huggingface.co/ wget https://repo.anaconda.com/minicon ...
- 使用SPA单页面跟MPA多页面的优缺点?
SPA vs MPA 深度解析 1. 概述 什么是 SPA? SPA(Single Page Application,单页面应用)是一种仅加载一个 HTML 页面,并通过 JavaScript 动态更 ...
- vue & font-awesome
vue & font-awesome // 使用npm安装依赖 npm install font-awesome@4.7.0 --save --verbose // 会在包管理文件(packa ...
- 记录 Windows关闭自动更新
- Mono GC
1.虽然是stw但mark阶段可以concurrent 2.并行mark就需要写屏障 3.unity的gc也不是扫描整个堆内存 https://schani.wordpress.com/2012/12 ...
- 前端速成之——Script
Script 1-引入js和函数调用 function函数:必然存在一个返回值,绝对不会书写 void,要么返回 undefine,要么返回 return 的数据 function etoak(val ...
- 代码随想录第二十五天 | Leecode 491. 非递减子序列、46. 全排列、47. 全排列 II
Leecode 491. 非递减子序列 题目描述 给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 .你可以按 任意顺序 返回答案. 数组中可能含有重 ...
- Windows安装PostgreSQL、PostGIS数据库的方法
本文介绍在Windows电脑中,下载.安装.部署并运行PostgreSQL与PostGIS数据库服务的方法. PostgreSQL是一种功能强大的开源关系型数据库管理系统(RDBMS),以其稳 ...
- [随记]-SpringMVC中的handler到底是什么东西
HandlerMapping 初始化时候的 HandlerMapping 有,按顺序排列: requestMappingHandlerMapping beanNameHandlerMapping -& ...