In my previous article’s you have seen how to export page data as a JSON format using servlet, now, I am going to explain exporting page content as JSON using sling models exporter, using sling model exporter you can get below advantages
- No need to write servlet to export data as JSON format
- You can use same code which is written using sling models to render content and to export as JSON format
The below things are developed on AEM 6.3 so, we do not need to install any other dependencies
Sling model exporter is very useful when you want to publish your data to third party system’s or consuming within the site using ajax request if you have sling models and wants to serialize them, by providing @Exporter annotations to the existing sling models you can convert your model as CaaS based URL
Here, I am serializing list collections component data, the text property I am returning as it is and also returning child nodes of the configured path which is a nodePath property
Step 1: create a model
Here, I have created a simple list collection model which contains three properties getText(), getLinks() and getMessage()
- The getText() returns whatever data is authored in the authoring dialog
- The getLinks() read path from the authoring dialog and return all child nodes
- The getMessage() returns static text
If you see the below code, the sling model exporter is not only serializing injected properties it is also serializing custom properties which are getMessage()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
package com.aem.toolkit.core.models; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Named; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.models.annotations.Default; import org.apache.sling.models.annotations.DefaultInjectionStrategy; import org.apache.sling.models.annotations.Exporter; import org.apache.sling.models.annotations.ExporterOption; import org.apache.sling.models.annotations.Model; import com.day.cq.wcm.api.Page; @Model(adaptables = Resource.class, resourceType = "examples/components/content/listcollection", defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) @Exporter(name = "jackson", extensions = "json", options = { @ExporterOption(name = "MapperFeature.SORT_PROPERTIES_ALPHABETICALLY", value = "true"), @ExporterOption(name = "SerializationFeature.WRITE_DATES_AS_TIMESTAMPS", value = "false") }) public class ListCollectionModel { public static java.util.List<PageBean> links = new ArrayList<PageBean>(); Resource resource; @Inject @Named("sling:resourceType") @Default(values = "No resourceType") protected String resourceType; @Inject @org.apache.sling.models.annotations.Optional private String text; @Inject @org.apache.sling.models.annotations.Optional private String nodePath; private String message; @Inject private Resource res; @Inject private ResourceResolver resourceResolver; @PostConstruct protected void init() { message = "Welcome to keys and strokes technical blog"; } public List<PageBean> getLinks() { resource = resourceResolver.resolve(nodePath); links.clear(); if (resource != null) { Iterator<Resource> linkResources = resource.listChildren(); linkResources.forEachRemaining(res -> populateModel(res)); } return links; } public void populateModel(Resource resource) { PageBean link = new PageBean(); Page page = resource.adaptTo(Page.class); if (page != null) { if (page.getTitle() != null) { link.setTitle(page.getTitle()); link.setPath(page.getPath()); } links.add(link); } } public String getMessage() { return message; } public String getText() { return text; } } |
The resourceType is an optional one, here I am assigning it to my custom listcollection component, which is resourceType = “examples/components/content/listcollection”
The sling models exporter uses Jackson framework which helps us serialize models as JSON format so, you need to provide exporter name as “jackson” and extensions should be “json”
The selector is optional one, if you don’t provide anything then it will take default selector which is “model”
Once, the build and deployment is done then test it using HTL and Rest based Url
Step 2: Test it using HTL
Check below screenshot using HTL, I am rendering the list collection model data
The output is something like below
Step 3: Test it with the REST-based URL
If you hit the URL then you should see something like below, here the “model” is selector
1 |
http://localhost:4506/content/examples/en/jcr:content/root/responsivegrid/listcollection.model.json |
Step 4: Ignore properties
In some use cases where you don’t want to export all the properties as JSON format, there, you can use Jackson ignore annotation, check the below code and I would recommend you to refer this link to get more information on jackson annotations Jackson Annotations, if you use this then the property will not be serialized
1 2 |
@JsonIgnore private String message; |
But, for this, you need to load Jackson dependencies
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.5.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.5.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.3</version> </dependency> |
Step 5: prior versions of AEM
If you are working on prior version’s of AEM 6.3 then you must load below sling model 1.3.0 dependencies and remaining things are same
1 2 3 4 5 6 7 8 9 10 11 12 |
<dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.models.api</artifactId> <version>1.3.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-atinject_1.0_spec</artifactId> <version>1.0</version> <scope>provided</scope> </dependency> |
Download Code
-
Mahesh Sah