如何用Java代码在AEM事件监听器中集成Akamai FastPurge API
集成Akamai FastPurge API到AEM事件监听器
第一步:修复原监听器代码的语法错误
你的原代码存在多处语法问题,先修正基础逻辑:
import org.osgi.service.event.EventHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.day.cq.replication.ReplicationAction; import com.day.cq.replication.ReplicationActionType; public class PublishListener implements EventHandler { private static final Logger logger = LoggerFactory.getLogger(PublishListener.class); @Override public void handleEvent(org.osgi.service.event.Event event) { try { logger.info("Event type:{}", event.getTopic()); ReplicationAction action = ReplicationAction.fromEvent(event); if (action.getType().equals(ReplicationActionType.ACTIVATE)) { logger.info("Page Published: {}", action.getPath()); } if (action.getType().equals(ReplicationActionType.DEACTIVATE) || action.getType().equals(ReplicationActionType.DELETE)) { logger.info("Page Deactivated/Deleted: {}", action.getPath()); } } catch (Exception e) { logger.error("Error processing event", e); } } }
第二步:添加Akamai FastPurge依赖
在你的AEM项目pom.xml中引入Akamai EdgeGrid客户端依赖:
<dependency> <groupId>com.akamai.edgegrid</groupId> <artifactId>edgegrid-signer-core</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>com.akamai.edgegrid</groupId> <artifactId>edgegrid-signer-apache-http-client</artifactId> <version>4.0.1</version> </dependency>
第三步:封装Akamai Purge服务
创建独立的服务类处理Akamai认证和缓存失效请求:
import com.akamai.edgegrid.signer.ClientCredential; import com.akamai.edgegrid.signer.apachehttpclient.ApacheHttpClientEdgeGridInterceptor; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; public class AkamaiPurgeService { private static final Logger logger = LoggerFactory.getLogger(AkamaiPurgeService.class); private final ClientCredential credential; private final String purgeEndpoint; public AkamaiPurgeService(String clientToken, String clientSecret, String accessToken, String host) { this.credential = ClientCredential.builder() .clientToken(clientToken) .clientSecret(clientSecret) .accessToken(accessToken) .host(host) .build(); this.purgeEndpoint = String.format("https://%s/purge/v3/invalidate/url", host); } public void invalidateUrls(String[] urls) { try (CloseableHttpClient httpClient = HttpClients.custom() .addInterceptorFirst(new ApacheHttpClientEdgeGridInterceptor(credential)) .build()) { HttpPost post = new HttpPost(purgeEndpoint); post.setHeader("Content-Type", "application/json"); // 构造JSON请求体 String requestBody = String.format("{\"objects\": %s}", convertToJsonArray(urls)); post.setEntity(new StringEntity(requestBody)); HttpResponse response = httpClient.execute(post); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode >= 200 && statusCode < 300) { logger.info("Akamai Purge succeeded for URLs: {}", String.join(", ", urls)); } else { logger.error("Akamai Purge failed with status code: {}", statusCode); } } catch (IOException e) { logger.error("Error executing Akamai Purge", e); } } private String convertToJsonArray(String[] urls) { StringBuilder sb = new StringBuilder("["); for (int i = 0; i < urls.length; i++) { sb.append("\"").append(urls[i]).append("\""); if (i != urls.length - 1) sb.append(","); } sb.append("]"); return sb.toString(); } }
第四步:整合到AEM事件监听器(带OSGi配置)
通过OSGi配置管理Akamai认证信息,避免硬编码:
- 创建OSGi配置接口
import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.ObjectClassDefinition; @ObjectClassDefinition(name = "Akamai FastPurge Configuration") public @interface AkamaiPurgeConfig { @AttributeDefinition(name = "Client Token") String clientToken(); @AttributeDefinition(name = "Client Secret") String clientSecret(); @AttributeDefinition(name = "Access Token") String accessToken(); @AttributeDefinition(name = "Akamai Host") String host(); @AttributeDefinition(name = "Published Site Base URL") String baseSiteUrl() default "https://your-production-domain.com"; }
- 修改监听器类
import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import org.osgi.service.event.EventConstants; import org.osgi.service.event.EventHandler; import org.osgi.service.metatype.annotations.Designate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.day.cq.replication.ReplicationAction; import com.day.cq.replication.ReplicationActionType; @Component(service = EventHandler.class, property = { EventConstants.EVENT_TOPIC + "=" + ReplicationAction.EVENT_TOPIC }) @Designate(ocd = AkamaiPurgeConfig.class) public class PublishListener implements EventHandler { private static final Logger logger = LoggerFactory.getLogger(PublishListener.class); private AkamaiPurgeService akamaiPurgeService; private String baseSiteUrl; @Activate protected void activate(AkamaiPurgeConfig config) { this.akamaiPurgeService = new AkamaiPurgeService( config.clientToken(), config.clientSecret(), config.accessToken(), config.host() ); this.baseSiteUrl = config.baseSiteUrl(); } @Override public void handleEvent(org.osgi.service.event.Event event) { try { ReplicationAction action = ReplicationAction.fromEvent(event); if (action == null) { logger.warn("Failed to extract ReplicationAction from event"); return; } String pagePath = action.getPath(); ReplicationActionType actionType = action.getType(); String publishedUrl = convertPathToUrl(pagePath); if (publishedUrl == null) { logger.warn("Cannot convert path to published URL: {}", pagePath); return; } // 触发缓存失效 if (ReplicationActionType.ACTIVATE.equals(actionType) || ReplicationActionType.DEACTIVATE.equals(actionType) || ReplicationActionType.DELETE.equals(actionType)) { logger.info("Triggering Akamai Purge for URL: {}", publishedUrl); akamaiPurgeService.invalidateUrls(new String[]{publishedUrl}); } } catch (Exception e) { logger.error("Error processing replication event", e); } } // 将AEM页面路径转换为发布后的公开URL private String convertPathToUrl(String pagePath) { // 根据你的站点路径规则调整,示例:/content/my-site/en/home.html -> https://domain.com/en/home.html if (pagePath.startsWith("/content/")) { String relativePath = pagePath.replaceFirst("/content/[^/]+/", ""); return baseSiteUrl + "/" + relativePath; } return null; } }
关键注意事项
- 在AEM的OSGi控制台中配置Akamai认证信息(Client Token、Client Secret等可从Akamai Control Center获取)
- 确保AEM服务器能访问Akamai的Purge API端点
- 建议将Purge操作异步化(比如通过AEM Job Manager),避免阻塞事件处理线程
- 测试阶段优先使用Akamai Staging环境验证
内容的提问来源于stack exchange,提问作者Bhavani K
相关产品推荐
相关产品推荐

