Problem Statement:
What is the best way to use Sling model?
Requirements:
Need to create sling model with best practices like OOTB components and increase the extensibility of the component and security.
Introduction:
The Sling model is a basic POJO, the class is annotated with @Model and the adaptable class. Fields that need to be injected are annotated with recommended injectors.
Its commonly used for injecting component resources and handling manipulation on those properties
Create a Sling model interface
Create a Sling model interface class and impl package with its implementation this helps in the long run when we are trying to write extra features by creating versions for the same component:
Create Interface Class – HelloWorldModel
In the below code, we can see an interface that extends Component and a few constants and methods which increases the security
package com.mysite.core.models;
import com.adobe.cq.wcm.core.components.models.Component;
import org.osgi.annotation.versioning.ConsumerType;
@ConsumerType
public interface HelloWorldModel extends Component {
/**
* if required by multiple classes
*/
String PN_PARENT_PAGE = "navigationRoot";
/**
* Returns the hellow world message
*
* @return the message containing resourcetype and page path.
*/
default String getMessage() {
throw new UnsupportedOperationException();
}
}
Create Implementation Class – HelloWorldModelImpl
package com.mysite.core.models.impl;
import static org.apache.sling.api.resource.ResourceResolver.PROPERTY_RESOURCE_TYPE;
import java.util.Optional;
import javax.annotation.PostConstruct;
import org.apache.sling.api.SlingHttpServletRequest;
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.Exporter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import com.adobe.cq.export.json.ExporterConstants;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.mysite.core.models.HelloWorldModel;
@Model(adaptables = SlingHttpServletRequest.class, adapters = {HelloWorldModel.class}, resourceType = HelloWorldModelImpl.RESOURCE_TYPE)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME , extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class HelloWorldModelImpl implements HelloWorldModel {
public static final String RESOURCE_TYPE = "mysite/components/content/hello";
@ValueMapValue(name=PROPERTY_RESOURCE_TYPE, injectionStrategy=InjectionStrategy.OPTIONAL)
@Default(values="No resourceType")
protected String resourceType;
@SlingObject
private Resource currentResource;
@SlingObject
private ResourceResolver resourceResolver;
private String message;
@PostConstruct
protected void init() {
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
String currentPagePath = Optional.ofNullable(pageManager)
.map(pm -> pm.getContainingPage(currentResource))
.map(Page::getPath).orElse("");
message = "Hello World!\n"
+ "Resource type is: " + resourceType + "\n"
+ "Current page is: " + currentPagePath + "\n";
}
public String getMessage() {
return message;
}
}
Implementation class will implement and adapters to interface class HellWorldModel
Please make sure
- Default adaption(adaptables) strategy is preferably SlingHTTPRequest compared or Resource
- We should always add Jackson exporter so that the model will be export ready
- Make sure always using relevant injector instead of @inject annotations refer for all the injectors: https://sling.apache.org/documentation/bundles/models.html
- if multiple fields have optional injection, then add the following code to the class to make all the variables as optional
@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
Project structure

AEM Core Image component:
References