Hello,
Exploring the use of Model class which can be used for HTL components. I see below two usages
@Model(adaptables = {SlingHttpServletRequest.class}) Seen here
@Model(adaptables = {Resource.class}) Seen in the archetype HelloWorldModel.java
What is the difference in using either of them? I checked Apache Sling :: Sling Models but unable to find use case comparision.
I have also see in one of the Github AEM projects where declaration of class is followed after @Model(adaptables = {SlingHttpServletRequest.class, Resource.class}). But when I see what is there inside the class or the @PostConstruct method, I am unable to tell the requirement of the adaptables type that we define before the class declaration.
I tried switching the values for HelloWorldModel.java from "Resource.class" to "SlingHttpServletRequest.class", in that case I had to use @inject for Resource otherwise I was using @self for Resource
//I. Using adaptables=Resource.class
@Model(adaptables=Resource.class)
public class HelloWorldModel {
@Inject
private SlingSettingsService settings;
//@Named gets the property with name. Here the value "sling:resourceType" does not match "reourceType", hence @Named is used.
@Inject @Named("sling:resourceType") @Default(values="No resourceType")
protected String resourceType;
private String message;
//@SlingObject
@Inject
private ResourceResolver resourceResolver;
@Self
private Resource resource;
//After completion of all injects, @PostConstruct is called. Methods/variables to be used in component can be added here.
@PostConstruct
protected void init() {
message = "\tHello World!\n";
message += "\tThis is instance: " + settings.getSlingId() + "\n";
message += "\tResource type is: " + resourceType + "\n";
if (resourceResolver != null) {
message += "\ttest id from RR: " + resourceResolver.getUserID() + "\n";
}
if (resource != null) {
message += "\tresource path: " + resource.getPath();
}
}
public String getMessage() {
return message;
}
}
//II. Using adaptables=SlingHttpServletRequest.class
@Model(adaptables=SlingHttpServletRequest.class)
public class HelloWorldModel {
@Inject
private SlingSettingsService settings;
//@Named gets the property with name. Here the value "sling:resourceType" does not match "reourceType", hence @Named is used.
@Inject @Named("sling:resourceType") @Default(values="No resourceType")
protected String resourceType;
private String message;
//@SlingObject
@Inject
private ResourceResolver resourceResolver;
@Inject
private Resource resource;
//After completion of all injects, @PostConstruct is called. Methods/variables to be used in component can be added here.
@PostConstruct
protected void init() {
message = "\tHello World!\n";
message += "\tThis is instance: " + settings.getSlingId() + "\n";
message += "\tResource type is: " + resourceType + "\n";
if (resourceResolver != null) {
message += "\ttest id from RR: " + resourceResolver.getUserID() + "\n";
}
if (resource != null) {
message += "\tresource path: " + resource.getPath();
}
}
public String getMessage() {
return message;
}
}
In both cases output on component was same.
Please guide.
Shubham
Solved! Go to Solution.
Views
Replies
Total Likes
When using Resource you can reuse without a UI in mind, when using request you can also access request-info.
When using Resource you can reuse without a UI in mind, when using request you can also access request-info.
And adding to Feike's statement: In many cases it doesn't matter which one you use. It would recommend to use just the Resource.class, because it gives you the flexibility to use this model also in non-request scenarios.
Jörg
According to the sling documentation,
https://sling.apache.org/documentation/bundles/models.html
Many Sling projects want to be able to create model objects - POJOs which are automatically mapped from Sling objects, typically resources, but also request objects. Sometimes these POJOs need OSGi services as well.
So, if we are trying to adapt a resource using following statement
Demo demo = resource.adaptTo(Demo.class);
so that we can reference to their values directly using the model object instead of extracting the valueeMap from the resource and getting the property values using the names, then the model, in our case Demo should definetly have adaptables as Resource.class otherwise we wont be able to adapt the resource and access the values.
Also, if we want to use to Sling objects like currentPage, currentStyle etc in our model then our model should definetly have SlingHttpServletRequest.class as adaptables.
Resource.class would simply work if we just want to access resource properties.
@rubalkour welcome to the AEM community. And thank you for sharing your answer here. looking forward to more SMEs like you inside the AEM community.
Views
Likes
Replies