我正在尝试使用 AEM 的默认模型导出器导出页面。该页面包含多个组件,其中一些组件具有多个字段。当我访问 homepage.model.json 时,JSON 没有多字段。
carousel: {
:type: "mysite/components/public/carousel",
title: "Test title"
}
我到处寻找解决方案。在互联网上的每个地方,他们都建议为我的组件创建一个导出器:
@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 时它仍然不包括在内:
carousel: {
:type: "mysite/components/public/carousel",
title: "Test title"
}
所以据我了解,我有两个选择:
制作页面导出器并拥有大量自定义代码。
接受我无法拥有一个包含我想要的所有 JSON 数据的页面。
我尝试制作一个自定义页面导出器,其逻辑是迭代所有子级和子级,以便用最少的代码获取正确的 JSON。我尝试获取每个组件的导出器模型,但 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
// PostConstructs are called after all the injection has occurred, but before the Model object is returned for use.
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 {
// If the resource is not a component, recursively process its children
processResource(childResource, pageData);
}
}
}
}
}
您的类是 Sling 模型,而不是 OSGi 服务,因此我不希望
@Reference
注释在这种情况下工作。这可能就是为什么它会出现为null
。要将 OSGi 服务注入 Sling 模型,您需要 @OSGiService
注入器特定注释。
@OSGiService
private ModelFactory modelFactory;
此外,在这种情况下您不一定需要使用
ModelFactory
。这在基于路径注入外部资源时非常有用。对于 Sling 模型中的子资源,有更方便的 API 可用。空安全可能存在一些边缘情况,具体取决于模型的具体功能以及您想要如何处理验证,但这对于简单的情况应该可以正常工作:
@ChildResource
List<ComponentModel> slides;