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
Solved! Go to Solution.
Views
Replies
Total Likes
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.
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!
Views
Replies
Total Likes
@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.
Views
Replies
Total Likes
Views
Replies
Total Likes
Views
Replies
Total Likes
Views
Replies
Total Likes
@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?
Views
Replies
Total Likes
Views
Replies
Total Likes
@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.
Views
Replies
Total Likes
Views
Replies
Total Likes
@aemninja See the screenshot below:
Based on the code that I have shared this is what output I am getting.
Views
Replies
Total Likes
Views
Replies
Total Likes
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.
Views
Likes
Replies
Views
Likes
Replies