You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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认证信息,避免硬编码:

  1. 创建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";
}
  1. 修改监听器类
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 07:20:06