May 13, 2020
Estimated Post Reading Time ~

Sling Models

There are 2 ways of getting access to data in AEM, both have their own uses

Sling Models

Sling models is a library that converts a Resource in the jcr:repository into a java POJO, while you can do basic processing in the PostConstruct method, this is a simple translation process.
A Resource is a java representation of a node in the jcr:repository with a set of properties
AEM Resource
The following code will represent the above image node
package com.sample.core.models;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Default;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Optional;
import org.apache.sling.settings.SlingSettingsService;

@Model(adaptables=Resource.class)
public class Image {
@Inject @Named("jcr:primaryType")
protected String primaryType;

@Inject
@Named("fileReference")
@Default(values="/content/dam/notFound.png")
private String fileReference;

@Inject
@Named("name")
@Optional
private String name;

private String message;

@PostConstruct
protected void init() {
message = "an image for "+ name +" has been added";
}

public String getMessage() {
return message;
}

public String getName()
{
return name;
}

public String getFileReference()
{
return fileReference;
}
}
The main annotation to define this as a model is
@Model(adaptables=Resource.class)
While the main case is to make it adaptable to a Resource, you can make it adaptable to any other type. i.e. if you only want to get information from AEM Pages then doing @Model(adaptables=Page.class) would return null if the resource being adapted is not adaptable as a class.
Resource resource = ...
Image image = resource.adaptTo(Image.class);
Converting the properties from the resource into fields in the POJO is done with the following annotations
  • Inject
    • Defines the field is injectable
  • Named
    • Defines the name of the property that the field represents
    • If not defined then the field name is used as the property name
  • Default
    • Defines a default value if the value is not present
  • Optional
    • Defines if the value has to be present in the resource
    • If not set and the value is not present an exception will be thrown
    • to make a resource backward compatible, any new fields added should be made Optional so that they don't fail
    • Fails to adapt the resource if a non-optional field is not available in the jcr:repository
As can also be seen in the example we can do some post-processing of the object. By adding the PostConstruct annotation we define a method that will be called once the object has been built and it's fields populated. This is very useful for calculated fields or if you need to do an additional lookup. i.e one of the fields is a path to another object and you need to read that object to get some of the fields that you want to expose.


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.