Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

How to dynamically get parent path inside do get method In servlet

Avatar

Level 4

Dear Team,

 

I have written below servlet for getting path inside the do get method. But I am not able to achieve it.

 

************************* MY JAVA Class ************************

 

import java.io.IOException;

import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.Servlet;
import javax.servlet.ServletException;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
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.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Servlet that lists all the events listed in AEM. The {@link SlingSafeMethodsServlet} shall be
* used for HTTP methods that are idempotent. For write operations use the
* {@link SlingAllMethodsServlet}.
*
*/
@component(service = Servlet.class, property = { "sling.servlet.methods=" + HttpConstants.METHOD_GET,
"sling.servlet.paths=" + "/bin/content/api/v1/getEventsListBypath2" })
public class EventsListBypathServlet2 extends SlingAllMethodsServlet {


private static final long serialVersionUID = 1L;

private static final Logger LOGGER = LoggerFactory.getLogger(EventsListBypathServlet.class);


@Override
protected void doGet(final SlingHttpServletRequest req, final SlingHttpServletResponse resp) throws ServletException, IOException {
String eventsPath2 = req.getSession().getId();
LOGGER.info("eventsPath2 in EventListBypath servlet:::"+ eventsPath2);

ResourceResolver resourceResolver = req.getResourceResolver();
Session session1 = resourceResolver.adaptTo(Session.class);
String userId = session1.getUserID();
try {
LOGGER.info("userId in EventListBypath servlet:::"+ userId + session1.getAttributeNames().toString() +session1.getRootNode());
} catch (RepositoryException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

Resource jcrResource = resourceResolver.getResource("testevent2023-9-3");

ValueMap jcrProperties = null;
String parentPath = null;
if (jcrResource != null) {
jcrProperties = jcrResource.adaptTo(ValueMap.class);
LOGGER.info("jcrProperties in EventListBypath servlet::: " + jcrProperties);
parentPath = jcrProperties.get("cq:parentPath", String.class);
LOGGER.info("parentPath in EventListBypath servlet::: " + parentPath);
}

}


}

 

******************************* My CRX Content ***********************

subnaik_0-1678335340372.png

 

************************ My requirement ******************

Whenever I am  hitting this servlet (http://localhost:4502/bin/content/api/v1/getEventsListBypath2) then I should see all the parent path of all the events inside /content/dam/content-admin/events/event-detail/test

 

BUt currently , I am getting parent value as null.

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

@subnaik : if you dont want to hard code this path , Then you can do below options.

1) you can pass as a request parameter to this servlet as

http://localhost:4502/bin/content/api/v1/getEventsListBypath2?path=/content/dam/content-admin/events...

 

@Override
protected void doGet(final SlingHttpServletRequest req, final SlingHttpServletResponse resp) throws ServletException, IOException {
String eventsPath2 = req.getSession().getId();

String damPath = req.getParamter("path") + "/jcr:content";
LOGGER.info("eventsPath2 in EventListBypath servlet:::"+ eventsPath2);

ResourceResolver resourceResolver = req.getResourceResolver();
Session session1 = resourceResolver.adaptTo(Session.class);
String userId = session1.getUserID();
try {
LOGGER.info("userId in EventListBypath servlet:::"+ userId + session1.getAttributeNames().toString() +session1.getRootNode());
} catch (RepositoryException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

Resource jcrResource = resourceResolver.getResource(damPath);

 

2) Otherwise , you can write a query to find the cq:ParentPath under the root path and from the results you can iterate and display.

may be root path as /content/dam/content-admin

 

Thanks,

Siva

 

Thanks,
Siva

View solution in original post

7 Replies

Avatar

Community Advisor

HI @subnaik :

You need to provide the path to get Resource.

Resource jcrResource = resourceResolver.getResource("testevent2023-9-3");

 

replace with 

 

Resource jcrResource = resourceResolver.getResource("/content/dam/content-admin/events/event-detail/test/testevent2023-9-3/jcr:content");

 

and one more observation is @component has to be replaced with @Component

 

as you are using doGet () method only , it is better to use SlingSafeMethodServlet   instead of SlingAllMethodSevlet

 

Thanks,

Siva

Thanks,
Siva

Avatar

Level 4

I do not want to hard code this path "/content/dam/content-admin/events/event-detail/test/testevent2023-9-3/jcr:content"

 

I want I should get this cq:parentpath dynamically whenever the servlet will call .

Avatar

Correct answer by
Community Advisor

@subnaik : if you dont want to hard code this path , Then you can do below options.

1) you can pass as a request parameter to this servlet as

http://localhost:4502/bin/content/api/v1/getEventsListBypath2?path=/content/dam/content-admin/events...

 

@Override
protected void doGet(final SlingHttpServletRequest req, final SlingHttpServletResponse resp) throws ServletException, IOException {
String eventsPath2 = req.getSession().getId();

String damPath = req.getParamter("path") + "/jcr:content";
LOGGER.info("eventsPath2 in EventListBypath servlet:::"+ eventsPath2);

ResourceResolver resourceResolver = req.getResourceResolver();
Session session1 = resourceResolver.adaptTo(Session.class);
String userId = session1.getUserID();
try {
LOGGER.info("userId in EventListBypath servlet:::"+ userId + session1.getAttributeNames().toString() +session1.getRootNode());
} catch (RepositoryException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

Resource jcrResource = resourceResolver.getResource(damPath);

 

2) Otherwise , you can write a query to find the cq:ParentPath under the root path and from the results you can iterate and display.

may be root path as /content/dam/content-admin

 

Thanks,

Siva

 

Thanks,
Siva

Avatar

Community Advisor

@subnaik 

page path / current page path can be passed to the servlet as queryparameter and can be processed afterwards.

 

Avatar

Level 4

@Rohit_Utreja , how can I get the current page inside servlet ?

 

Also I have updated code with query string like below.

 

************************* Updated JAVA code*************************

@Override
protected void doGet(final SlingHttpServletRequest req, final SlingHttpServletResponse resp) throws ServletException, IOException {
String eventsPath2 = req.getSession().getId();
LOGGER.info("eventsPath2 in EventListBypath servlet:::"+ eventsPath2);
String damPath = req.getParameter("path") + "/jcr:content";
LOGGER.info("damPath in EventListBypath servlet:::"+ damPath);

String path = req.getParameter("path") != null ? req.getParameter("path") : "";
LOGGER.info("path in EventListBypath servlet:::"+ path);

ResourceResolver resourceResolver = req.getResourceResolver();
Session session1 = resourceResolver.adaptTo(Session.class);
String userId = session1.getUserID();
try {
LOGGER.info("userId in EventListBypath servlet:::"+ userId + session1.getAttributeNames().toString() +session1.getRootNode());
String queryString = "SELECT * FROM [dam:AssetContent] WHERE ISDESCENDANTNODE ([/content/dam/content-admin/events/event-detail/test])";

QueryManager queryManager = session1.getWorkspace().getQueryManager();
Query query = queryManager.createQuery(queryString, "JCR-SQL2");

LOGGER.info("Executing query");
QueryResult queryResults = query.execute();
NodeIterator nodeIterator = queryResults.getNodes();
while(nodeIterator.hasNext()) {
String resourcePath = nodeIterator.nextNode().getParent().getPath();
LOGGER.info("resource path is {}",resourcePath);
}
} catch (RepositoryException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

 

******************************************************

But my value is coming like below..

 

resource path is /content/dam/content-admin/events/event-detail/test/testevent2023-9-3

 

Here only I want cq:parentpath that is /content/dam/content-admin/events/event-detail/test for all the node inside /content/dam/content-admin/events/event-detail/test

 

subnaik_0-1678374520383.png

 

Avatar

Community Advisor

@subnaik :

 

now you can pass resourcePath to below code which you have wrote in your previous comment

Resource jcrResource = resourceResolver.getResource(resourcePath+"jcr:content");

ValueMap jcrProperties = null;
String parentPath = null;
if (jcrResource != null) {
jcrProperties = jcrResource.adaptTo(ValueMap.class);
LOGGER.info("jcrProperties in EventListBypath servlet::: " + jcrProperties);
parentPath = jcrProperties.get("cq:parentPath", String.class);
LOGGER.info("parentPath in EventListBypath servlet::: " + parentPath);
}

 

parentPath will give you the cq:parentPath

Thanks,
Siva

Avatar

Level 4

Thanks @SivakumarKanoori , it is working fine and we can mark this as correct answer