Expand my Community achievements bar.

July 31st AEM Gems Webinar: Elevate your AEM development to master the integration of private GitHub repositories within AEM Cloud Manager.
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.