Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

Issues with retrieving Sling Model values in JSP

Avatar

Level 4

Hello Community - I am getting an error while retrieving the values from Sling Model and using it in JSP. Not sure what is the issue? Can someone help with this?

 

Error:

org.apache.sling.models.impl.ModelAdapterFactory Could not adapt to model
org.apache.sling.models.factory.ModelClassException: Unable to find a useable constructor for model class com.test.aem.core.models.TestModel
at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:686) [org.apache.sling.models.impl:1.4.12]

 

Sling Model:

 

package com.test.aem.core.models;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import javax.jcr.Node;
import javax.jcr.RepositoryException;

/**
* Model used to set & get values
*/
@Model(adaptables = {SlingHttpServletRequest.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class TestModel {

private SlingHttpServletRequest request;

public TestModel(SlingHttpServletRequest request) {
this.request = request;
}

private String articleInfo;
private String articleFound = "false";

public String getArticleInfo() {
return articleInfo;
}

public void setArticleInfo(String articleInfo) {
this.articleInfo = articleInfo;
}

public String getArticleFound() {
return articleFound;
}

public void setArticleFound(String articleFound) {
this.articleFound = articleFound;
}

@PostConstruct
protected void init() {

if (request.getQueryString() != null) {
this.setArticleFound("true");
}
String jcrPath = "/content/test/jcr:content/Par/config";
Node nodeVal = request.getResourceResolver().getResource(jcrPath).adaptTo(Node.class);
try {

articleInfo = nodeVal != null ? nodeVal.getProperty("articleInfo").getString() : "";

this.setArticleInfo(articleInfo);

} catch (RepositoryException e) {

}

}

}

 

JSP:

<%@include file="/libs/foundation/global.jsp"%>
<%@page session="false" import="com.test.aem.core.models.TestModel"%>
<c:set var="SlingArticleModel" value="<%= resource.adaptTo(TestModel.class)%>"/>
<div>Article Info : ${SlingArticleModel.articleInfo}</div>

 

@BrianKasingli@Vijayalakshmi_S

 

 

 

 
1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @aemninja,

Looks like you are trying to inject the SlingHttpServletRequest via Constructor(couldn't find inject annotation though, not sure if its a typo while pasting the code here in the post), Remove the constructor and you can use either @Self or @SlingObject for injecting SlingHttpServletRequest.

 

View solution in original post

13 Replies

Avatar

Community Advisor

Hi @aemninja 

 

Your Model class is adapted to SlingHttpServletRequest, so in JSP also you should adapt the class into SlingHttpServletRequest(slingRequest in global.jsp).

I see you have adapted into Resource object which is why it's failing.

 

Please update the below line in JSP and it will resolve the issue:

 

<c:set var="SlingArticleModel" value="<%= slingRequest.adaptTo(TestModel.class)%>"/>

 

Thanks! 

Avatar

Level 4
@Asutosh_Jena_ - I am still not able to retrieve the value after changing it to slingRequest. Earlier I tried with adapting to resource as well.

Avatar

Community Advisor

@aemninja Adapting to Resource will not work as you are retrieveing the request object.

I just tried the below code and it works for me.

 

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

private static final Logger log = LoggerFactory.getLogger(TestModel.class);

@SlingObject
private SlingHttpServletRequest request;

private String articleInfo;
private String articleFound = "false";

@PostConstruct
protected void init() {
log.info("***** :: init :: Start :: *****");
if (request.getQueryString() != null) {
this.setArticleFound("true");
}
String jcrPath = "/content/we-retail/jcr:content";
Node nodeVal = request.getResourceResolver().getResource(jcrPath).adaptTo(Node.class);
try {
articleInfo = nodeVal != null ? nodeVal.getProperty("cq:conf").getString() : StringUtils.EMPTY;
this.setArticleInfo(articleInfo);
} catch (RepositoryException e) {
log.info("***** :: init :: RepositoryException :: *****", e);
}
log.info("***** :: init :: End :: *****");
}

public String getArticleInfo() {
return articleInfo;
}

private void setArticleInfo(String articleInfo) {
this.articleInfo = articleInfo;
}

public String getArticleFound() {
return articleFound;
}

private void setArticleFound(String articleFound) {
this.articleFound = articleFound;
}
}

 

<%@include file="/libs/foundation/global.jsp"%>
<%@page session="false" import="com.aem.core.models.TestModel"%>
<c:set var="SlingArticleModel" value="<%= slingRequest.adaptTo(TestModel.class)%>"/>
<div>Article Info : ${SlingArticleModel.articleInfo}</div>

 

This prints the cq:conf value as /conf/we-retail

 

Just check if you are getting any error. 

Avatar

Level 4
@Asutosh_Jena_ - what I meant is, I have already tried with adapting to resource in Sling Model and also in JSP.

Avatar

Community Advisor
Please try with the above code and let me know what error you are getting.

Avatar

Level 4
@Asutosh_Jena_ - I could see the values in the logs inside init() (i.e @PostConstruct) but I see the issue is with setting the value(setter).

Avatar

Community Advisor

@aemninja  What is the exact error you are getting while setting the value? I can see it's working as expected. When I am accessing with query parameter in the URL, it is setting the value as "true".

 

Please see the below code:

 

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

private static final Logger log = LoggerFactory.getLogger(TestModel.class);

@SlingObject
private SlingHttpServletRequest request;

private String articleInfo;
private String articleFound = "false";

@PostConstruct
protected void init() {
log.info("***** :: init :: Start :: *****");
if (request.getQueryString() != null) {
this.setArticleFound("true");
log.info("Article Found? -> {}", getArticleFound());
}
String jcrPath = "/content/we-retail/jcr:content";
Node nodeVal = request.getResourceResolver().getResource(jcrPath).adaptTo(Node.class);
try {
articleInfo = nodeVal != null ? nodeVal.getProperty("cq:conf").getString() : StringUtils.EMPTY;
this.setArticleInfo(articleInfo);
} catch (RepositoryException e) {
log.info("***** :: init :: RepositoryException :: *****", e);
}
log.info("***** :: init :: End :: *****");
}

public String getArticleInfo() {
return articleInfo;
}

private void setArticleInfo(String articleInfo) {
this.articleInfo = articleInfo;
}

public String getArticleFound() {
return articleFound;
}

private void setArticleFound(String articleFound) {
this.articleFound = articleFound;
}
}

 

Are you not able to see the value getting set in log when you are trying with query parameter?

 

What is the exact requirement? 

Avatar

Level 4
@Asutosh_Jena_ - I don't see any error this time but the value I am setting inside init() i.e this.setArticleInfo(articleInfo);, is not applied.

Avatar

Community Advisor

@aemninja As per your code, articleInfo will be set with the value only if /content/test/jcr:content/Par/config (the config node) node has a property called "articleInfo" and the property has some value. If the property is missing or if it does not contain any value it will set as EMPTY which is why you are getting it as empty.

 

Please check if the path above mentioned is a valid path. I will suggest to check the node and see if it contains any value, if not add the property and re run the test. Also you can replace the "" (EMPTY) with any other default String and check the it (just to ensure all are working fine).

That's why in my example I have mentioned the we-retail package which is exist in instance and returns result.

 

Avatar

Level 4
@Asutosh_Jena_ - Thanks for your reply. The property and the value is present in the node. I am able to print the "articleInfo" value in the init() menthod as well. The only issue is while setting the value, it is not assigning the value. articleInfo = nodeVal != null ? nodeVal.getProperty("cq:conf").getString() : StringUtils.EMPTY;

Avatar

Community Advisor

@aemninja See the screenshot below:

asutosh_jena_0-1622221300321.png

asutosh_jena_1-1622221315022.png

Based on the code that I have shared this is what output I am getting.

 

Avatar

Level 4
@Asutosh_Jena_ - I don't see any screenshot attached. can you send it again

Avatar

Correct answer by
Community Advisor

Hi @aemninja,

Looks like you are trying to inject the SlingHttpServletRequest via Constructor(couldn't find inject annotation though, not sure if its a typo while pasting the code here in the post), Remove the constructor and you can use either @Self or @SlingObject for injecting SlingHttpServletRequest.