Choosing The Right Adaptable In Sling Models: Resource Vs. SlingHttpServletRequest

While creating a sling model, we annotate the model with adaptables. It can be adaptable to a Resource.class, or SlingHttpServletRequest.class or both at a time. Let us understand the basic difference between these two adaptables first.

Difference between both

The basic difference between both adaptables is that The Resource is designed for data access and manipulation, independent of any user interface whereas, SlingHttpServletRequest, on the other hand, provides access to additional information about the incoming request. Let us see with examples:

Example: Resource Adaptable

@Model(adaptables = Resource.class)  // Specify adaptable type as Resource
public class SampleModel {

    // Inject property from content tree with optional default value
    @Inject(optional = true)
    @Named("title") // Specify property name if different from field name
    @Default("Default Title")
    private String title;

    // Inject child resource using path
    @ChildResource(path = "image")  
    private Resource imageResource;

    // Getter method for injected property
    public String getTitle() {
        return title;
    }

    // Access child resource property using adapter
    public String getImageUrl() {
        if (imageResource != null) {
            return imageResource.adaptTo(ValueMap.class).get("fileReference", String.class);
        }
        return "";
    }

    // Method to modify injected property (not recommended)
    public void setTitle(String title) {
        // This modification won't be reflected in the content tree
        this.title = title;
    }

    // Example method using SlingHttpServletRequest (not injected)
    public String getQueryString(SlingHttpServletRequest request) {
        return request.getQueryString();
    }
}

For data-centric tasks, Resource is a good choice as it’s not tied to user interfaces. If you need details about the incoming request, use the Request object.

Example: SlingHttpServletRequest adaptable

@Model(adaptables = SlingHttpServletRequest.class)
public class SampleModel {

    // Method to access request parameter
    public String getParameter(String name, SlingHttpServletRequest request) {
        return request.getParameter(name);
    }

    // Method to access request header
    public String getHeader(String name, SlingHttpServletRequest request) {
        return request.getHeader(name);
    }

    // Method to access request path
    public String getRequestPath(SlingHttpServletRequest request) {
        return request.getPathInfo();
    }

    // Method to access request method (GET, POST, etc.)
    public String getRequestMethod(SlingHttpServletRequest request) {
        return request.getMethod();
    }
}

The above code demonstrates how models can leverage the SlingHttpServletRequest adaptable scenario for tasks beyond content tree access.

When to use which one?

Use Resource adaptable when:

  • You primarily need to access and manipulate content tree data: properties, child resources, or hierarchical navigation.
  • You want a reusable model that can function independently of a user interface (UI) or specific request context.
  • You don’t require information specific to the current HTTP request.

Use SlingHttpServletRequest adaptable when:

  • You need to access request-specific information: parameters, headers, path, method, or other request details.
  • Your model logic relies on understanding the user’s interaction with the content through the request.
  • You want to perform actions related to the current request lifecycle.

Can we use both adaptable?

Yes. Depending on the requirement, you can use both adaptable in your sling model by adding the adaptable something like this:

@Model(adaptables = {Resource.class, SlingHttpServletRequest.class})
public class CombinedModel {

    // Injected property from content tree
    @Inject
    @Named("title")
    private String title;

    // Method to access request parameter and modify content based on it
    public void updateTitleFromParameter(String paramName, SlingHttpServletRequest request) {
        String newTitle = request.getParameter(paramName);
        if (newTitle != null) {
            // Modify content tree (assuming appropriate permissions)
            Resource resource = (Resource) request.getResource();
            resource.adaptTo(ModifiableValueMap.class).put("title", newTitle);
        }
    }

    // Getter method for injected property
    public String getTitle() {
        return title;
    }
}

Let us know in the comments section below if you have any further queries or doubts. 🙂

Spread the word!
0Shares

Leave a comment

Your email address will not be published. Required fields are marked *