AEM页面导出器未包含多字段组件问题求助
解决AEM默认页面模型导出器不包含多字段内容的问题
问题场景
使用AEM默认模型导出器导出包含多字段组件的页面时,访问homepage.model.json返回的JSON中缺少多字段数据:
carousel: { :type: "mysite/components/public/carousel", title: "Test title" }
已尝试操作及局部结果
为带多字段的carousel组件创建了自定义模型导出器:
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL, resourceType = {"mysite/components/public/carousel"}) @Exporter(name = "jackson", extensions = "json") public class CarouselModelImpl implements CarouselModel, ComponentModel { ... @Getter private List<CarouselBean> slides; ... }
此时单独访问组件导出地址homepage/jcr:content/carousel.model.json,能得到包含多字段的正确JSON:
{ title: "Test title", slides: [ { title: "slide title 1", description: null, ctaLabel: "cta label", ctaLink: "#", image: "/content/dam/mysite/Rectangle 2.png" }, { title: "slide title 2", description: null, ctaLabel: "cta label", ctaLink: "#", image: "/content/dam/mysite/image.png" } ] }
但访问页面级导出地址homepage.model.json时,多字段内容依然缺失,返回内容和最初一致。
自定义页面导出器遇到的问题
尝试创建自定义Page Exporter遍历子资源获取完整JSON,但调用modelFactory.getModelFromResource时modelFactory为null,代码如下:
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL, resourceType = {"mysite/components/public/structure/public-page"}) @Exporter(name = "jackson", extensions = "json") public class PageExporterServlet { private static final Logger log = LoggerFactory.getLogger(PageUtils.class); @Reference private ModelFactory modelFactory; @Reference private SlingScriptHelper slingScriptHelper; @Self private Resource resource; @Getter private String myTitle = "Test"; @Getter Map<String, Object> pageData = new HashMap<>(); @PostConstruct protected void init() { try { processResource(resource, pageData); } catch (Exception e) { log.debug(e.getMessage()); } } private void processResource(Resource resource, Map<String, Object> pageData) { if (resource != null) { Iterable<Resource> childResources = resource.getChildren(); for (Resource childResource : childResources) { ComponentModel componentModel = (ComponentModel) modelFactory.getModelFromResource(childResource); if (componentModel != null) { pageData.put(childResource.getPath(), componentModel.getData()); } else { processResource(childResource, pageData); } } } } }
可行解决方案
1. 修复ModelFactory空指针问题
@Model注解类中,@Reference无法直接完成OSGi服务注入,需改用@Inject配合@OSGiService注解获取ModelFactory:
@Inject @OSGiService private ModelFactory modelFactory;
替换原代码中的@Reference private ModelFactory modelFactory;,即可正确注入服务实例。
2. 优化页面资源遍历逻辑
调整遍历逻辑,只处理业务组件资源,避免无效递归:
private void processResource(Resource resource, Map<String, Object> pageData) { if (resource == null) return; // 仅处理业务组件(排除CQ系统组件) String resourceType = resource.getValueMap().get("sling:resourceType", String.class); if (resourceType != null && !resourceType.startsWith("cq:")) { try { ComponentModel componentModel = modelFactory.getModelFromResource(resource, ComponentModel.class); if (componentModel != null) { pageData.put(resource.getName(), componentModel.getData()); } } catch (Exception e) { log.error("Failed to load model for resource: {}", resource.getPath(), e); } } // 递归处理子资源 for (Resource child : resource.getChildren()) { processResource(child, pageData); } }
3. 替代方案:使用Core Components页面模型导出器
无需自定义代码,直接使用AEM Core Components提供的Page Model Exporter。只需确保页面资源类型继承自Core Components的Page组件,且自定义组件模型实现ComponentExporter接口,即可自动导出所有组件的完整数据(包括多字段)。
内容的提问来源于stack exchange,提问作者Stefanos Karakasis
相关产品推荐
相关产品推荐

