Sling Model with custom selector not working in AEM 6.5 | Community
Skip to main content
Level 2
November 18, 2021

Sling Model with custom selector not working in AEM 6.5

  • November 18, 2021
  • 2 replies
  • 7793 views

Hi All,

 

I am using a Sling model exporter to export json data in AEM 6.5 and using the selector "caas". When the selector is "model" , it works perfectly. However with custom selector , it shows the below error.

 

Invalid recursion selector value 'caas'

Cannot serve request to /content/abc/internal/exportsite/en/clientaccess/help/secondlevela/level3.caas.json in org.apache.sling.servlets.get.DefaultGetServlet

 

Already tried the below:

check if this helps - Re: Sling Exporter with custom selector

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

2 replies

Asutosh_Jena_
Community Advisor
Community Advisor
November 18, 2021

Hi @vikrams57194913 

 

Is /content/abc/internal/exportsite/en/clientaccess/help/secondlevela/level3 a page?

Did you try with /content/abc/internal/exportsite/en/clientaccess/help/secondlevela/level3/jcr:content.caas.json?

 

Thanks!

Level 2
November 18, 2021

I am getting blank page with the above link also, only getting response from model.json

 

Thanks

Vijayalakshmi_S
Level 10
November 19, 2021

Thanks now its work. But now when I am using Sling model delegation pattern for retrieving page get exported items I am getting Null pointer exception.

 

@Model(adaptables = SlingHttpServletRequest.class, adapters = { PageExporter.class,
ComponentExporter.class, Page.class }, resourceType = PageExporterImpl.RESOURCE_TYPE, defaultInjectionStrategy=DefaultInjectionStrategy.OPTIONAL)
@3484101(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,selector = "mobile",extensions = ExporterConstants.SLING_MODEL_EXTENSION)
//@Model(adaptables = Resource.class, resourceType="/apps/contentservices/components/structure/page", defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
//
//@Exporter(name = "jackson", selector="caas", extensions = "json", options = { @ExporterOption(name = "SerializationFeature.WRITE_DATES_AS_TIMESTAMPS", value = "true") })
public class PageExporterImpl implements PageExporter, Page{

protected static final String RESOURCE_TYPE = "contentservices/components/structure/page";

/** The logger. */
private final Logger logger = LoggerFactory.getLogger(PageExporterImpl.class);

/** The sling http servlet request. */
@1961677(injectionStrategy = InjectionStrategy.REQUIRED)
private SlingHttpServletRequest slingHttpServletRequest;

@ScriptVariable
protected com.day.cq.wcm.api.Page currentPage;

private Map<String, ComponentExporter> childModels = null;

protected String title;
protected String description;
@1961677 @2434638(type = ResourceSuperType.class)
private Page page;


@9944223
public String getTitle() {
return "title";
}
@9944223
public String getDescription() {
return description;
}

@9944223
public String getLanguage() {
return currentPage == null ? Locale.getDefault().toLanguageTag()
: currentPage.getLanguage(false).toLanguageTag();
}

@PostConstruct
protected void initModel() {
title = currentPage.getTitle();
description = currentPage.getDescription();

}


@9944223
public Map<String, ? extends ComponentExporter> getExportedItems() {
return page.getExportedItems();
}

@9944223
@JsonIgnore
public String getExportedType() {
// TODO Auto-generated method stub
return null;
}

}


We need to provide implementation for all methods and delegate. We can make use of lombok @Delegate annotation for this - https://www.initialyze.com/blog/2020/11/simplify-extending-sling-models-with-lombok/

 

Also, note that your custom interface(PageExporter) has methods in the same name as OOTB core Page interface. Cross check the same and rename/remove based on your need. 

 

You can use the below and see if it works. 

package com.aem.demoproject.core.models;

import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.export.json.ExporterConstants;
import com.day.cq.wcm.api.Page;
import lombok.experimental.Delegate;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Via;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.via.ResourceSuperType;

import javax.inject.Inject;
import java.util.Map;

@Model(adaptables = SlingHttpServletRequest.class, adapters = {com.adobe.cq.wcm.core.components.models.Page.class}, resourceType = PageExporterImpl.RESOURCE_TYPE)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, selector = "mobile", extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class PageExporterImpl implements com.adobe.cq.wcm.core.components.models.Page {

    protected static final String RESOURCE_TYPE = "demoproject/components/structure/page";

    @Inject
    private Page currentPage;

    @Delegate(types = com.adobe.cq.wcm.core.components.models.Page.class, excludes = Handled.class)
    @Self
    @Via(type = ResourceSuperType.class)
    private com.adobe.cq.wcm.core.components.models.Page pageDelegate;

    @Override
    public Map<String, ? extends ComponentExporter> getExportedItems() {
        return pageDelegate.getExportedItems();
    }

    public String getMessage() {
        return "Custom Page Exporter Impl";
    }

    protected static interface Handled {
        public Map<String, ? extends ComponentExporter> getExportedItems();
    }
}

Result :

 

September 21, 2022

Hi Vikram, 

Add the caas.json.jsp file in the project and update its content as below: 

 

/apps/cq/Page/caas.json.jsp 

<%@include file="/libs/cq/Page/proxy.jsp" %>

 

Update the workspace filter so changes are picked up: 

<filter root="/apps/cq/Page">

 

This should work. You can add multiple selectors with this way. 

 

Another solution is to combine your custom selector with the OOTB model selector e.g model.caas