Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events
SOLVED

Is it possible to get exportedItems of page in resource type servlet?

Avatar

Level 1

I have a simple resourceType servlet through which I want to fetch the path of the experience fragment present in the present in the page.

currently  I am getting only default properties but I want to see all the properties exported by .model.json extension but inside the servlet.

below is the code I am using.

 

instead of com.day.cq.wcm.api.Page if somehow I am able to adapt to com.adobe.cq.wcm.core.components.models.Page then I can use getExportedItems to get the child components . Please let me know how to achieve that 

 

 

 

import com.adobe.cq.sites.ui.designfield.datasources.Children;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.wcm.api.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.my.aem.project.core.models.HelloWorldModel;

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.apache.sling.servlets.annotations.SlingServletResourceTypes;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.propertytypes.ServiceDescription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;

@Component(service = { Servlet.class })
@SlingServletResourceTypes(
        resourceTypes="my-project/components/page",
        methods={HttpConstants.METHOD_POST,HttpConstants.METHOD_GET},
        selectors="s1",
        extensions="json")
@ServiceDescription("Simple Demo Servlet")
public class SimpleServlet extends SlingSafeMethodsServlet {
    private static final Logger LOGGER = LoggerFactory.getLogger(SimpleServlet.class);
    // private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(final SlingHttpServletRequest req,
            final SlingHttpServletResponse resp) throws ServletException, IOException {

                ObjectMapper objectMapper = new ObjectMapper();
                final Resource page = req.getResource();
                ResourceResolver resourceResolver = req.getResourceResolver();
                final String currentPagePath = page.getPath().substring(0, page.getPath().lastIndexOf('/'));
                Resource resource = resourceResolver.getResource(currentPagePath);
                if (Objects.nonNull(resource) && resource.isResourceType("cq:Page")) {

                Page currentPage = resource.adaptTo(Page.class);
                LOGGER.info("----------- Properties:-------------");
              LOGGER.info(objectMapper.writeValueAsString(currentPage.getProperties()));
                Resource pageContentResource = currentPage.getContentResource();
                com.adobe.cq.wcm.core.components.models.Page pageContentResourcePage = currentPage.adaptTo(com.adobe.cq.wcm.core.components.models.Page.class);        
  LOGGER.info(objectMapper.writeValueAsString(Objects.isNull(pageContentResourcePage)));  // gives result true 
LOGGER.info(objectMapper.writeValueAsString(pageContentResource.getResourceType()));
LOGGER.info("----------- pageResource:-------------");
            }
               resp.getWriter().write("Title = " + resource.getValueMap().get(JcrConstants.JCR_TITLE));
    }
}

 

 
1 Accepted Solution

Avatar

Correct answer by
Community Advisor

@mayurthedev Yes, you can get the page model json using the ModelFactory API like the following 

 

@Reference
private ModelFactory modelFactory;
--------------------
// this gives you the page.model.json if the request is associated with the page you requesting 
modelFactory.exportModelForRequest(request, "jackson", String.class, new HashMap<>())

 

you don't need to adaption to Page to get the exportedItems. 

View solution in original post

5 Replies

Avatar

Community Advisor

https://github.com/adobe/aem-core-wcm-components/blob/main/bundles/core/src/main/java/com/adobe/cq/w...

 

As per comment section in that page, its for the resourceTypes= /apps/core/wcm/components/page

 

/**
* Defines the {@code Page} Sling Model used for the {@code /apps/core/wcm/components/page} component.
*
* @since com.adobe.cq.wcm.core.components.models 11.0.0
*/

Avatar

Correct answer by
Community Advisor

@mayurthedev Yes, you can get the page model json using the ModelFactory API like the following 

 

@Reference
private ModelFactory modelFactory;
--------------------
// this gives you the page.model.json if the request is associated with the page you requesting 
modelFactory.exportModelForRequest(request, "jackson", String.class, new HashMap<>())

 

you don't need to adaption to Page to get the exportedItems. 

Avatar

Level 1

This results in MissingElementsException for me. I'm not getting why. Can you help what would be the cause

Avatar

Community Advisor

@mayurthedev  As mentioned in the JavaDoc, it is throwing because of missing elements when instantiating the Sling Model - https://sling.apache.org/apidocs/sling10/org/apache/sling/models/factory/MissingElementsException.ht...

 

Add a try-catch block to catch the exception and get the missing elements 

try {
                return modelFactory.exportModelFromRequest(model, "jackson", String.class, map);
            } catch (MissingElementsException e) {
                log.error("Unable to export sling model as JSON due to the following missing elements ", e);
                e.getMissingElements().stream().forEach(ele -> {
                    log.error("Missing element - {} ", ele.getElement());
                });
            }

 

Avatar

Level 1

Hey, I Tried this there are several things missing ..
I get this in return 

Could not inject all required fields into class  com.adobe.cq.wcm.core.components.internal.models.v2.PageImpl
 


I don't know how to resolve though .. Can you point me to an example on internet where this is implemented .. Sorry I am very new to AEM . my requirement is just to fetch only the required content properties from the child components.