在第1部分在本系列的文章中,我讨论了将AEM Asset Collection项转换为页面的JSON表示的方法。这使用Sling模型+ html组件模式获取集合项并根据资产类型在JSON中显示它们的值。特别是,Sling模型允许JSON呈现器在内容片段和svg中显示标记。它还支持AEM路径到二进制格式化的资产。
使用这种方法,第三方应用程序和服务可以使用JSON,以无头的方式使用AEM。使用这种方法,作者可以更新集合,而内容使用者可以在其JSON提要中看到这些集合更新。这已经是一个强大的解决方案,但我们可以在更新JSON方面添加一些自动化,并使其在面向客户/消费者的分派器域可用。
自动化JSON更新
让我们从自动化JSON更新开始。当作者在一个集合中添加或删除项时,这应该自动反映在JSON中。为此,我们需要向项目中添加一个JCR Event Listener类,它将监听更改并使用组件请求页面。你可以在这里找到这样一个类:
注:对a的引用CollectionsListenerConfig类。我们不需要硬编码到页面节点的路径,而是可以从配置中获得一个路径数组,以调用配置为JSON消费的一个或多个页面。
页面= config.pagesToUpdate ();
为了侦听集合的更改,我们使用Service用户创建会话。这是一种特殊类型的AEM用户主体,比真正的用户ID更适合后端服务任务。
然后可以使用创建的会话对象来设置侦听器。我们需要侦听属性的变化以及/content/dam/collections下实际节点的添加和删除。
.getObservationManager session.getWorkspace()()。addEventListener(这个事件。PROPERTY_ADDED |事件。PROPERTY_REMOVED |事件。PROPERTY_CHANGED |事件。NODE_ADDED |事件。NODE_REMOVED, "/content/dam/collections", true,null, null, false);
当其中一个事件发生时,将调用onEvent方法。方法中获取的数组中的每个页面都请求该方法CollectionsListenerConfig。它对每个页面使用一个简单的HTTP servlet请求,使用在activate方法中通过服务用户获得的相同资源解析器。
我们不关心在浏览器中呈现页面,只关心调用页面。这将导致Sling和html引擎处理在这些页面上配置的集合组件。因此,您可以使用最新的DAM收集数据触发对它们属性的更新。
现在,CollectionsListenerConfig类。这是一个简单的类,它使用ObjectClassDefinition注释来定义配置对象,使用AttributeDefinition注释来定义可配置字段。
@AttributeDefinition(name = "要更新的页面",description = "当DAM集合被更新或更改时,应该通过Sling调用的页面",type = AttributeType。STRING) STRING [] pagesToUpdate();
当这个类与bundle一起加载时,它的配置将被添加到OSGi配置管理服务的可配置项列表中(通过Felix OSGi实现提供)。AEM管理员可以在/system/console/configMgr下配置页面列表。该配置也可以包含在代码存储库中,位于特定于运行模式的配置文件夹下。
有了这些添加,该解决方案现在可以以可配置的方式自动更新JSON。
允许自动复制
我们可以做的另一件可选的事情是更新IncludeCollectionsModel类以允许自动复制。这里要做的一件重要的事情是确保复制只在作者身上进行。我们可以为此使用复制器API和外部化器。
类中添加了两个方法,checkIfAuthor和replicateContent.第一个方法是不言自明的,它是一个布尔方法,用于确定是否在Author上执行。
private boolean checkIfAuthor() {Setmodes = slingSettingsService.getRunModes();if (mode .contains(Externalizer.AUTHOR)) {return true;} else {return false;} }
第二个方法调用复制器API来复制页面。
public void replicatcontent (String path) {try {Session Session = resourceResolver.adaptTo(Session.class);复制因子。复制(会话,ReplicationActionType。激活路径);log.info("{}集合已被复制",LOG_PREFIX);} catch (ReplicationException e) {log.error(e.getMessage(), e);} }
复制调用需要一个会话、复制操作和资源路径。我们通过调整Sling提供的资源解析器来获得会话对象(这与组件中用于获得提供的集合路径的Sling:成员的资源解析器相同)。使用此会话的好处在于,它是在当前用户应用的acl的上下文中创建的。这意味着只有当服务用户或编辑组件的作者必须复制权限集以允许页面使用时,才会发生复制。
在提交组件属性更改之后调用此方法,因此复制的页面总是具有最新的更新。在调用此函数之前,我们检查以确保类正在一个作者上执行,并且只有在checkIfAuthor返回true。
resourceResolver.commit ();//如果在Author上运行,则复制该页面,以便发布者可以访问相同的JSON更新。全能影像经理全能影像经理= resource.getResourceResolver () .adaptTo (PageManager.class);Page currentPage = pageManager.getContainingPage(resource);if (checkIfAuthor() && currentPage != null){复制内容(currentPage. getpath ());}
通过所有这些变化,我们最大化了作者和出版商的自动更新。这里所做的一切都使用AEM内置的Sling、Node和Replicator api,以及内置的OSGi服务。这说明了扩展AEM已经很好的构建块的好处!