Adobe Experience Manager (AEM) 与 ActiveMQ 的集成可实现系统间的解耦和异步通信,以下是详细的集成步骤与代码实现:

一、环境准备

  1. AEM 环境:AEM 6.5+ 或 AEM as a Cloud Service
  2. ActiveMQ:版本 5.15+(推荐 5.17.x)
  3. Maven 项目:用于开发 AEM 组件和配置

二、ActiveMQ 配置

1. 启用 JMS 连接

修改 ActiveMQ 的 conf/activemq.xml,确保支持 OpenWire 协议:
<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>

2. 创建 JMS 用户(可选)

修改 conf/users.properties 添加专用用户:
jmsuser=jms password,users

三、AEM 集成步骤

1. 添加 ActiveMQ 依赖

在 AEM 项目的 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 配置

定义 ActiveMQ 连接工厂配置:
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 内容处理逻辑
}
}

六、验证集成效果

  1. 启动 ActiveMQ:
bin/activemq start
  1. 部署 AEM 包:将开发的 OSGi 组件打包部署到 AEM。
  2. 测试消息发送:
  3. 测试消息接收:
    • 实现消息消费者服务
    • 验证消息是否正确处理

七、常见问题与解决方案

  1. 连接失败
    • 检查 ActiveMQ 地址和端口
    • 确认防火墙未阻止通信(默认 61616 端口)
  2. 消息丢失
    • 确保使用 DeliveryMode.PERSISTENT
    • 检查 ActiveMQ 持久化配置
  3. AEM 组件无法访问 JMS 服务
    • 检查 OSGi 配置是否正确
    • 确认依赖包已正确导入
通过以上步骤,你可以实现 AEM 与 ActiveMQ 的完整集成,实现系统间的异步通信和解耦。根据实际需求,你还可以进一步优化配置,如使用 JNDI 管理连接工厂、配置集群模式提高可用性等。
 
 
 
 
 
 
 

AEM 与 ActiveMQ 集成方案详解的更多相关文章

  1. Server-U FTP与AD完美集成方案详解

    最近咱有个任务,那就是把公司的文件服务器.FTP服务器.邮件服务器进行迁移并作相应的整合.登陆后台查看了,公司目前正在使用的方案.FTP服务器使用的是Server-u FTP,验证方式选择的windo ...

  2. 最佳实战Docker持续集成图文详解

    最佳实战Docker持续集成图文详解 这是一种真正的容器级的实现,这个带来的好处,不仅仅是效率的提升,更是一种变革:开发人员第一次真正为自己的代码负责——终于可以跳过运维和测试部门,自主维护运行环境( ...

  3. 安卓集成发布详解(二)gradle

    转自:http://frank-zhu.github.io/android/2015/06/15/android-release_app_build_gradle/ 安卓集成发布详解(二) 15 Ju ...

  4. 莱特币ltc在linux下的多种挖矿方案详解

    莱特币ltc在linux下的多种挖矿方案详解 4.0.1 Nvidia显卡Linux驱动Nvidia全部驱动:http://www.nvidia.cn/Download/index.aspx?lang ...

  5. 基于rem的移动端响应式适配方案(详解) 移动端H5页面的设计稿尺寸大小规范

    基于rem的移动端响应式适配方案(详解) : https://www.jb51.net/article/118067.htm 移动端H5页面的设计稿尺寸大小规范 http://www.tuyiyi.c ...

  6. SpringBoot系列(六)集成thymeleaf详解版

    SpringBoot系列(六)集成thymeleaf详解版 1. thymeleaf简介  1. Thymeleaf是适用于Web和独立环境的现代服务器端Java模板引擎.  2. Thymeleaf ...

  7. App域名劫持之DNS高可用 - 开源版HttpDNS方案详解(转)

      http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=209805123&idx=1&sn=ced8d67c3e2cc3 ...

  8. 性能百万/s:腾讯轻量级全局流控方案详解

    WeTest 导读 全新的全局流控实现方案,既解决了目前流控的实现难点,同时保证运行稳定且流控准确的前提下,实现更简单,部署成本更低,容灾能力更强. 该方案组件化之后,可以推广到别的有需要的部门使用, ...

  9. P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解

    1.内容概述 P2P即点对点通信,或称为对等联网,与传统的服务器客户端模式(如下图"P2P结构模型"所示)有着明显的区别,在即时通讯方案中应用广泛(比如IM应用中的实时音视频通信. ...

  10. Spring Boot 集成 FreeMarker 详解案例(十五)

    一.Springboot 那些事 SpringBoot 很方便的集成 FreeMarker ,DAO 数据库操作层依旧用的是 Mybatis,本文将会一步一步到来如何集成 FreeMarker 以及配 ...

随机推荐

  1. Oracle 修改SYS、system用户密码

      by:授客 QQ:1033553122 概念 SYS用户是Oracle中权限最高的用户,而SYSTEM是一个用于数据库管理的用户.在数据库安装完之后,应立即修改SYS,SYSTEM这两个用户的密码 ...

  2. 如何删除Docker Swarm中的Node

    好吧,我又回来了...断了那么久主要是因为懒...现在有空会更新一些docker相关的知识.本文主要是总结下在工作中需要管理Docker Swarm中的Node遇到的问题:如何删除一个Swarm中的N ...

  3. 05 过拟合(over-fitting)与正则化(regularization)

    1. 什么是Overfitting 我们希望神经网络模型能够找到数据集中的一般规律,从而帮助我们预测未知数据.这个过程是通过不断地迭代优化损失函数(也就是预测值和实际值的误差)而实现的.然而随着误差进 ...

  4. 项目实战 TS

    项目实战 TS 通用技巧 新手先 any 再填坑,老手先定义数据结构写逻辑 遇到新场景,没把握快速,先用 any 再填坑,填坑的过程也是 TS 技能满满提升的过程. TS 发现潜在问题 1)复杂逻辑, ...

  5. Tinyhttpd 源代码初步解读

    Tinyhttpd 是很早以前的一个 web 服务器程序,由 C 语言编写,整个程序十分小巧,源码只有几百行.它一般不适合用于生产环境,因为它很简单,只实现了读取 html 以及 Get / POST ...

  6. 小白必看的java完整下载攻略!(在Typora中有图片参考)

    Java下载 在浏览器上搜索JDK(2024年最新版是22,本人下载的是21) 点击官网下载,会跳到Oracle官网,需要注册账号才可下载 根据自己的电脑型号选择下载(本人下载的是64的) 正常情况下 ...

  7. 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明

    5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明 @ 目录 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明 1. Exchanges 交换机的 ...

  8. 从DeepSeek看算法备案&大模型备案

    一.deepseek的备案情况 (一)算法备案情况 在算法备案系统网站上,北京深度求索人工智能基础技术研究有限公司和杭州深度求索人工智能基础技术研究有限公司分别进行了两个算法备案.从公司名称来看,正如 ...

  9. ShardingJdbc学习笔记

    Mysql主从复制遇到问题 安装mysql Install/Remove of the Service Denied!错误的解决办法

  10. JIT 编译后的代码存储位置

    JIT 编译后的代码存储位置 1. 存储位置 JIT 编译后的本地机器代码被存储在 JVM 的 Code Cache(代码缓存区)中. Code Cache 是 JVM 内存的一部分,用于保存 JIT ...