Article summary

Summary

Discusses how to export Experience Manager node data (an AEM resource) by using a Sling Model Exporter.  This developer article uses Java APIs located in the org.apache.sling.models.annotations.Model package to create the Sling Model Exporter. 

A special thank you to Shivani Garg, a great AEM commuity member whom writes a lot of useful blogs, for contributing code and testing this article to ensure it works.

Digital Marketing Solution(s) Adobe Experience Manager 6.4
Audience Developer
Required Skills Java, HTML, JQuery
Version 6.4

Introduction

You can create an Experience Manager Sling Model Exporter to export Experience Manager data as JSON. You can invoke a Sling Model Exporter by using an HTTP Restful call and get back data. For example, assume that you want to get details of an image component located in the We Retail site:

 http://localhost:4502/editor.html/content/we-retail/us/en/experience.html

The following illustration shows the image component. 

slingmodela
An image component located in the We Retail Site

You can use a Sling Model Exporter to get component details returned within JSON, as shown in the following illustration.  

slingmodelb
Component data returned by a Sling Model Exporter

To invoke the Sling Model Exporter, you can use this URL: 

http://localhost:4502/content/we-retail/us/en/experience/jcr:content/root/responsivegrid/heroimage.model.tidy.json

The data is retrieved from the AEM JCR located here: 

/content/we-retail/us/en/experience/jcr:content/root/responsivegrid/heroimage

The following illustration shows this node. 

slingmodelc
The node from which the Sling Model Exporter exports data

You can create a Sling Model Exporter by using Java APIs located in the org.apache.sling.models.annotations package.

 

Note:

For more informatioin about Sling Model Exporters, see Understanding Sling Model Exporters in AEM and Exporter Framework

Create an AEM Maven 11 archetype project

You can create an archetype project by using the Maven archetype plugin. In this example, assume that the working directory is C:\AdobeCQ.

maven
Maven Archetype 10 generated files

Note:

If you have not setup Maven in your development environment, see Creating an Adobe Experience Manager 6.4 Project using Adobe Maven Archetype 13.

To create an Experience Manager archetype project, perform these steps:

1. Open the command prompt and go to your working directory (for example, C:\AdobeCQ).

2. Run the following Maven command:

mvn org.apache.maven.plugins:maven-archetype-plugin:2.4:generate -DarchetypeGroupId=com.adobe.granite.archetypes -DarchetypeArtifactId=aem-project-archetype -DarchetypeVersion=11 -DarchetypeCatalog=https://repo.adobe.com/nexus/content/groups/public/

3. When prompted, specify the following information:

  • groupId - slingModelExport
  • artifactId - slingModelExport
  • version - 1.0-SNAPSHOT
  • package - com.aem.community.export
  • appsFolderName - slingModelExport
  • artifactName - slingModelExport
  • componentGroupName - slingModelExport
  • contentFolderName - slingModelExport
  • cssId - slingModelExport
  • packageGroup - slingModelExport
  • siteName - slingModelExport

4. WHen prompted, specify Y.

5. Once done, you will see a message like:

[INFO] BUILD SUCCESS
[INFO] ----------------------------------------------------------------------
[INFO] Total time: 01:42 min
[INFO] Finished at: 2016-04-25T14:34:19-04:00
[INFO] Final Memory: 16M/463M
[INFO] ----------------------------------------------------------------------

6. Change the working directory to slingModelExport and then enter the following command.

mvn eclipse:eclipse

After you run this command, you can import the project into Eclipse as discussed in the next section.

Add Java files to the Maven project using Eclipse

To make it easier to work with the Maven generated project, import it into the Eclipse development environment, as shown in the following illustration.

project
An Eclipse project

The Eclipse project that you work in to build the OSGi bundle that uses HTL API is slingModelExport.core. You do not have to work in the other projects under slingModelExport.

Note:

Do not worry about the errors reported in Eclipse. It does not read the POM file where the APIs are resolved. You build the bundle with Maven. Eclipse is used to edit the Java files and the POM file.

The next step is to add a Java file to the com.aem.community.export.core.models package. The Java class is named ModelComponent and uses these Sling Model annotations.

@Model(adaptables = Resource.class, resourceType = { "weretail/components/content/heroimage" }, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)

@Exporter(name = "jackson", extensions = "json", options = { @ExporterOption(name = "SerializationFeature.WRITE_DATES_AS_TIMESTAMPS", value = "true") })
 

Notice the resourceType property within the @Model annotation references weretail/components/content/heroimage. This corresponds to the component in the JCR that is used to return component details in JSON format. The @Exporter annotation specifies to return the data as JSON (as shown at the start of this article).

The data members in the class with a @inject annotation correspond to the properties of the heroimage component whose values are returned within JSON. For example, this data member: 

@Inject
String title;

 Corresponds to the title property of the component located here.

titleprops
The title property that belongs to the HeroImage component

The following code represents the ModelComponent class.

package com.aem.community.export.core.models;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.ExporterOption;


import javax.inject.Inject;
import javax.inject.Named;

@Model(adaptables = Resource.class, resourceType = { "weretail/components/content/heroimage" }, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
@Exporter(name = "jackson", extensions = "json", options = { @ExporterOption(name = "SerializationFeature.WRITE_DATES_AS_TIMESTAMPS", value = "true") })
public class ModelComponent {

	@Inject
	String title;

	@Inject
	String heading;

	@Inject
	String buttonLabel;

	@Inject
	String buttonLinkTo;

	@Inject
	String fileReference;

	@Inject
	@Named("sling:resourceType")
	String slingResourceType;

	public String getHeading() {
		return heading;
	}

	public String getButtonLabel() {
		return buttonLabel;
	}

	public String getButtonLinkTo() {
		return buttonLinkTo;
	}

	public String getSlingResourceType() {
		return slingResourceType;
	}

	public String getTitle() {
		return title;
	}

	public String getFileReference() {
		return fileReference;
	}

}

Modify the Maven POM file

Add the following POM dependencies to the POM file located at C:\AdobeCQ\slingModelExport.

<dependency>
    <groupId>com.adobe.aem</groupId>
    <artifactId>uber-jar</artifactId>
    <version>6.4.0</version>
    <classifier>apis</classifier>
    <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>

You need to modify two POM files. The first one is the parent POM file shown in this illustration.

maven
Parent POM

Add the dependency shown above to the Parent POM file. Next, modify the POM file located at C:\AdobeCQ\slingModelExport\core. The following code represents this POM file.

<?xml version="1.0" encoding="UTF-8"?>
<!--
 |  Copyright 2015 Adobe Systems Incorporated
 |
 |  Licensed under the Apache License, Version 2.0 (the "License");
 |  you may not use this file except in compliance with the License.
 |  You may obtain a copy of the License at
 |
 |      http://www.apache.org/licenses/LICENSE-2.0
 |
 |  Unless required by applicable law or agreed to in writing, software
 |  distributed under the License is distributed on an "AS IS" BASIS,
 |  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 |  See the License for the specific language governing permissions and
 |  limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>slingModelExport</groupId>
        <artifactId>slingModelExport</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>slingModelExport.core</artifactId>
    <packaging>bundle</packaging>
    <name>slingModelExport - Core</name>
    <description>Core bundle for slingModelExport</description>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.sling</groupId>
                <artifactId>maven-sling-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <id>bundle-manifest</id>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>manifest</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <instructions>
                        <!-- Import any version of javax.inject, to allow running on multiple versions of AEM -->
                        <Import-Package>javax.inject;version=0.0.0,*</Import-Package>
                        <Sling-Model-Packages>
                            com.aem.community.export.core
                        </Sling-Model-Packages>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <!-- OSGi Dependencies -->
        <dependency>
            <groupId>com.adobe.aem</groupId>
            <artifactId>uber-jar</artifactId>
            <classifier>obfuscated-apis</classifier>
        </dependency>
    
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-atinject_1.0_spec</artifactId>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>osgi.core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>osgi.cmpn</artifactId>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>osgi.annotation</artifactId>
        </dependency>
        <!-- Other Dependencies -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.jcr</groupId>
            <artifactId>jcr</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.adobe.aem</groupId>
            <artifactId>uber-jar</artifactId>
            <classifier>apis</classifier>
        </dependency>
        <dependency>
            <groupId>org.apache.sling</groupId>
            <artifactId>org.apache.sling.models.api</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
        </dependency>
        <dependency>
            <groupId>junit-addons</groupId>
            <artifactId>junit-addons</artifactId>
        </dependency>
    </dependencies>
</project>

Build the OSGi bundle using Maven

To build the OSGi bundle by using Maven, perform these steps:

  1. Open the command prompt and go to the C:\AdobeCQ\slingModelExport.
  2. Run the following maven command: mvn -PautoInstallPackage install.
  3. The OSGi component can be found in the following folder: C:\AdobeCQ\slingModelExport\core\target. The file name of the OSGi component is slingModelExport.core-1.0-SNAPSHOT.jar.

The command -PautoInstallPackage automatically deploys the OSGi bundle to AEM.

Add an Image Component to the We Retail site

Open the We Retail site at the following URL: 

http://localhost:4502/editor.html/content/we-retail/us/en/experience.html

Next, drag the HeroImage component from the side rail onto the page, as shown in the following illustration (this is the component used by the Sling Model Exporter).

weretail
Drag the HeroImage component onto the AEM page

Open the dialog and enter values, as shown in this illustration (these are the property values displayed by the Sling Model Exporter). 

dialog
Properties for the HeroImage component set using a dialog

Notice that these values are stored at this JCR location: 

/content/we-retail/us/en/experience/jcr:content/root/responsivegrid/heroimage

See the image at the start of this article. These are the values that are returned by the Sling Model Exporter.

Enter the following URL: 

http://localhost:4502/content/we-retail/us/en/experience/jcr:content/root/responsivegrid/heroimage.model.tidy.json

The response is JSON data as shown at the start of this article. 

See also

Join the AEM community at: Adobe Experience Manager Community

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License  Twitter™ and Facebook posts are not covered under the terms of Creative Commons.

Legal Notices   |   Online Privacy Policy