Expand my Community achievements bar.

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