Obtaining resourceresolver in Sling Model

Avatar

Avatar

viki1101

Avatar

viki1101

viki1101

19-11-2020

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)

Accepted Solutions (1)

Accepted Solutions (1)

Avatar

Avatar

BrianKasingli

MVP

Avatar

BrianKasingli

MVP

BrianKasingli
MVP

20-11-2020

@viki1101, 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();
            }
            
        }
    }

}

 

 

Answers (7)

Answers (7)

Avatar

Avatar

Arun_Patidar

MVP

Total Posts

2.9K

Likes

1.0K

Correct Answer

831

Avatar

Arun_Patidar

MVP

Total Posts

2.9K

Likes

1.0K

Correct Answer

831
Arun_Patidar
MVP

22-11-2020

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.

Avatar

Avatar

Manjunath_K

Avatar

Manjunath_K

Manjunath_K

20-11-2020

Hi @viki1101 

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

 

@ScriptVariable
private ValueMap pageProperties;


pageProperties.get(JcrConstants.JCR_TITLE);

 

Avatar

Avatar

TUmesh

Avatar

TUmesh

TUmesh

20-11-2020

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

 

Avatar

Avatar

Anudeep_Garnepudi

Avatar

Anudeep_Garnepudi

Anudeep_Garnepudi

19-11-2020

Hi @viki1101 

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

Avatar

Avatar

Sandeep6

Avatar

Sandeep6

Sandeep6

19-11-2020

Hi @viki1101 ,

 

Please try @SlingObject to get resource resolver.

please follow below link for reference .

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

Thanks,

Sandeep.

Avatar

Avatar

Ankur_Khare

MVP

Avatar

Ankur_Khare

MVP

Ankur_Khare
MVP

19-11-2020

@inject

private ResourceResolver resolver;

 

Then u can use this resolver to access path..

Avatar

Avatar

Anudeep_Garnepudi

Avatar

Anudeep_Garnepudi

Anudeep_Garnepudi

23-11-2020

@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?