Difference between adaptables values in a Model class

snbaem 07-12-2018

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

Accepted Solutions (1)

Accepted Solutions (1)

Answers (1)

Answers (1)

Jörg_Hoh
Employee
08-12-2018

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