Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
BedrockMission!

Learn more

View all

Sign in to view all badges

SOLVED

Obtaining resourceresolver in Sling Model

v1101
Level 5
Level 5

Hello Community - I am trying to obtain the resource from the existing resource path using Sling model (Not servlet). I am able to get the properties (buttonlabel) values for the component path.

I need some additional properties from the jcr:content of the given path. When I pass the given path to the resource resolver, it throws some exception. could someone please help here?

 

@Model(adaptables = { Resource.class,SlingHttpServletRequest.class})
public class ResourcePathModel {
private String buttonlabel;
private Resource jcrResource;

@inject
@source("sling-object")
private ResourceResolver resourceResolver;

public ResourcePathModel(Resource resource) {
ValueMap resVal = resource.getValueMap(); //This is the resource.getPath() - /content/we-retail/blog/en/jcr:content/root/container/content/hero_image
this.buttonlabel = resVal.get("buttonlabel", String.class); //Here I am able to retrieve the values with no issues.
try {
jcrPath = "/content/weretail/blog/en/jcr:content";
jcrResource = resourceResolver.getResource(jcrPath); //Having issues and getting exception here.
if (jcrResource != null) {
jcrNode = jcrResource.adaptTo(Node.class);
jcrTitle = jcrNode.getProperty("jcr:title").getString();
}
} catch (RepositoryException e) {
LOG.info("RepositoryException " + e);
}
}
}

Exception:
org.apache.sling.models.factory.MissingElementsException: Could not inject all required fields into class com.uhg.uhcmr.aem.core.models.ActiveElementNodeModel
at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:765)
at org.apache.sling.models.impl.ModelAdapterFactory.internalCreateModel(ModelAdapterFactory.java:448)

1 Accepted Solution
BrianKasingli
Correct answer by
Community Advisor
Community Advisor

@v1101, your code looks accurate,

 

    @ScriptVariable
    private ResourceResolver resolver;

 

Take a look at this Sling Models Reference Guide, its a good example of how you can inject AEM objects via AEM Sling Model Injectors, https://sourcedcode.com/blog/aem/aem-sling-model-injectors-annotations-reference-guide 

Also, working Sling Model Example (simplified way): Note, you can get the resource's value map using the Sling Model Injectors, @ValueMapValue

 

package uk.co.whitbread.shared.bundle.slingmodels.desktop.components.hdhoteldetails.topsection;

import com.day.cq.wcm.api.Page;
import lombok.Getter;
import org.apache.commons.lang.StringUtils;
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.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ScriptVariable;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;

import javax.annotation.PostConstruct;

@Getter
@Model(adaptables = {SlingHttpServletRequest.class, Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ResourcePathModel {

    @ScriptVariable
    private ResourceResolver resolver;

    @ScriptVariable
    private Page currentPage;

    @ValueMapValue
    private String myComponentCustomProperty;
    
    @Getter
    private String exportTitle;
    
    @PostConstruct
    public void init() {
        if (StringUtils.isNotEmpty(myComponentCustomProperty)) {
            Resource resource = resolver.getResource(myComponentCustomProperty);
            if (resource != null) {
                // DO LOGIC HERE
                exportTitle = "something";
            } else {
                exportTitle = currentPage.getTitle();
            }
            
        }
    }

}

 

 

View solution in original post

14 Replies
Ankur_Khare
Community Advisor
Community Advisor

@inject

private ResourceResolver resolver;

 

Then u can use this resolver to access path..

Ankur_Khare
Community Advisor
Community Advisor
Which aem version u are in and what error it is giving pls add the code how u tried and aem version
Ankur_Khare
Community Advisor
Community Advisor
I just tried on aem 6.5 with @inject private ResourceResolver resolver; resolver.getResource('path'); its working fine
v1101
Level 5
Level 5


import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Source;
import org.apache.sling.models.annotations.Via;
import org.apache.sling.models.annotations.injectorspecific.ScriptVariable;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.jsoup.helper.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import java.util.stream.Stream;

@Model(adaptables = { Resource.class,SlingHttpServletRequest.class})
public class ResourcePathModel {
private String buttonlabel;

private Resource jcrResource;
private String jcrPath;

@inject
private ResourceResolver resourceResolver;

public ResourcePathModel (Resource resource) {
this.buttonlabel = childResources.get("buttonlabel", String.class);
ValueMap resVal = resource.getValueMap();
this.buttonlabel = resVal.get("buttonlabel", String.class); //Here I am able to retrieve the values with no issues.
try {
jcrPath = "/content/weretail/blog/en/jcr:content";
jcrResource = resourceResolver.getResource(jcrPath); //Having issues and getting exception here.
if (jcrResource != null) {
jcrNode = jcrResource.adaptTo(Node.class);
jcrTitle = jcrNode.getProperty("jcr:title").getString();
}
}catch (RepositoryException e) {
LOG.info("RepositoryException " + e);
}

}
}

Ankur_Khare
Community Advisor
Community Advisor
Kindly add teh complete code what u tried, like below- @inject private ResourceResolver resolver; resolver.getResource('path');
Sandeep6
Level 5
Level 5

Hi @v1101 ,

 

Please try @SlingObject to get resource resolver.

please follow below link for reference .

https://sling.apache.org/documentation/bundles/models.html 

Thanks,

Sandeep.

Anudeep_Garnepudi
Community Advisor
Community Advisor

Hi @v1101 

You don't have a default Constructor (Constructor without any parameters) because of which your Model is failing to instantiate. As you are adding your own Constructor Java Compiler will not provide the default one, you must add explicitly. Add below two line it should work.

public ResourcePathModel() {

}

AG

Umesh_Thakur
Community Advisor
Community Advisor

I don't know if you have any specific reason to get the resourceResovler's stand alone object. If nothing special, you can get resourceResolver and Resource from request as well as you already have servletRequest adaptable in your model. there will be advantage like you not need to close the resourceResolver explicitly.

if Not you can use @SlingObject annotation to get the resolver as your model is adaptables to slingRequest.

OR you can also get currentPage with @inject annotation to get the current page and its jcr node.

Don't stick to only one solution to your problem as there are multiple option available to hande it.

And if possible use injection strategy like 

defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL that will make your code more flexible.

 

hope this will help.

Umesh Thakur

 

BrianKasingli
Correct answer by
Community Advisor
Community Advisor

@v1101, your code looks accurate,

 

    @ScriptVariable
    private ResourceResolver resolver;

 

Take a look at this Sling Models Reference Guide, its a good example of how you can inject AEM objects via AEM Sling Model Injectors, https://sourcedcode.com/blog/aem/aem-sling-model-injectors-annotations-reference-guide 

Also, working Sling Model Example (simplified way): Note, you can get the resource's value map using the Sling Model Injectors, @ValueMapValue

 

package uk.co.whitbread.shared.bundle.slingmodels.desktop.components.hdhoteldetails.topsection;

import com.day.cq.wcm.api.Page;
import lombok.Getter;
import org.apache.commons.lang.StringUtils;
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.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ScriptVariable;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;

import javax.annotation.PostConstruct;

@Getter
@Model(adaptables = {SlingHttpServletRequest.class, Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ResourcePathModel {

    @ScriptVariable
    private ResourceResolver resolver;

    @ScriptVariable
    private Page currentPage;

    @ValueMapValue
    private String myComponentCustomProperty;
    
    @Getter
    private String exportTitle;
    
    @PostConstruct
    public void init() {
        if (StringUtils.isNotEmpty(myComponentCustomProperty)) {
            Resource resource = resolver.getResource(myComponentCustomProperty);
            if (resource != null) {
                // DO LOGIC HERE
                exportTitle = "something";
            } else {
                exportTitle = currentPage.getTitle();
            }
            
        }
    }

}

 

 

View solution in original post

Manjunath_K
Community Advisor
Community Advisor

Hi @v1101 

You can directly access current page properties in Sling Models as mentioned below.

 

@ScriptVariable
private ValueMap pageProperties;


pageProperties.get(JcrConstants.JCR_TITLE);

 

Arun_Patidar
Community Advisor
Community Advisor

Could you please try to get page property by injecting page object using below:

@ScriptVariable
    private Page currentPage;

and try to add default injection policy as well

defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL 

 

---------------------------

Note : just FYI

the @inject may not work because of multiple type of adaptable used. If you want to use only @inject annotations then you have to inject using @Via.

Anudeep_Garnepudi
Community Advisor
Community Advisor

@kautuk_sahni 

Here logic is written in Constructor, there is no default Constructor or Constructor injection. Adding default Constructor or Constructor injection should work here right?