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.

AEM Cloud Service - Sites SPA add additional page properties in sling model response jackson export | AEM Community Blog Seeding




AEM Cloud Service - Sites SPA add additional page properties in sling model response jackson export by Sreekanth Choudry Nalabotu


AEM Cloud Version : 2021.3.5087.20210322T071003Z-210225 (March 22, 2021)

The default sling model exporter com.adobe.aem.spa.project.core.internal.impl.PageImpl for page resource types with super type spa-project-core/components/page does not add custom or additional properties on the page content node like vanity path to the response. You can always create a project specific model implementation for your pages extending com.adobe.aem.spa.project.core.models.Page, however for adding just few additional properties a simple filter might be an easier solution...

Add a filter apps.experienceaem.sites.core.filters.EAEMExtendPageModelFilter with filter pattern sling.filter.pattern=.*.model.json to intercept model requests, capture the response and add additional properties (eg. sling:vanityPath) to the response reading it from cq:PageContent node

package apps.experienceaem.sites.core.filters;

import org.apache.commons.lang3.StringUtils;
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.wrappers.SlingHttpServletResponseWrapper;
import org.apache.sling.commons.json.JSONObject;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;

service = Filter.class,
immediate = true,
name = "Expereince AEM Sling Model Response Modifier Servlet Filter",
property = {
Constants.SERVICE_RANKING + ":Integer=-99",
public class EAEMExtendPageModelFilter implements Filter {
private static Logger log = LoggerFactory.getLogger(EAEMExtendPageModelFilter.class);

private static final String SLING_VANITYPATH = "sling:vanityPath";
private static final String SLING_VANITYPATH_JSON_PROP = "eaemVanityPath";
private static final String CHILDREN = ":children";

public void init(FilterConfig filterConfig) throws ServletException {

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
SlingHttpServletRequest slingRequest = (SlingHttpServletRequest)request;

String uri = slingRequest.getRequestURI();

chain.doFilter(request, response);

SlingHttpServletResponse modelResponse = getModelResponse((SlingHttpServletResponse) response);

chain.doFilter(slingRequest, modelResponse);

PrintWriter responseWriter = response.getWriter();

responseWriter.write(getModifiedContent(modelResponse.toString(), slingRequest));
}catch(ServletException e){
throw new ServletException("Error at EAEMExtendPageModelFilter.this.doFilter()");

SlingHttpServletResponse getModelResponse(SlingHttpServletResponse response) {
SlingHttpServletResponse modelResponse = new DefaultSlingModelResponseWrapper(response);
return modelResponse;

private String getModifiedContent(String origContent, SlingHttpServletRequest slingRequest){
String modifiedContent = origContent;

JSONObject model = new JSONObject(origContent);

addAddnPropertiesInPageModel(model, slingRequest);

modifiedContent = model.toString();
}catch(Exception e){
log.error("Error at EAEMExtendPageModelFilter.this.getModifiedContent(origContent={}) {}", origContent, e);
modifiedContent = origContent;

return modifiedContent;

private void addAddnPropertiesInPageModel(JSONObject model, SlingHttpServletRequest slingRequest) throws Exception{

JSONObject childrenModel = model.getJSONObject(CHILDREN);
Iterator childrenItr = childrenModel.keys();
ResourceResolver resolver = slingRequest.getResourceResolver();
Resource pageContent;

while(childrenItr.hasNext()) {
String key = childrenItr.next();
JSONObject childData = childrenModel.getJSONObject(key);

pageContent = resolver.getResource(key + "/jcr:content");

if(pageContent == null){

ValueMap vm = pageContent.getValueMap();

String slingVanityPath = vm.get(SLING_VANITYPATH, "");

childData.put(SLING_VANITYPATH_JSON_PROP, slingVanityPath);

public void destroy() {

private class DefaultSlingModelResponseWrapper extends SlingHttpServletResponseWrapper {
private CharArrayWriter writer;

public DefaultSlingModelResponseWrapper (final SlingHttpServletResponse response) {
writer = new CharArrayWriter();

public PrintWriter getWriter() throws IOException {
return new PrintWriter(writer);

public String toString() {
return writer.toString();

Read Full Blog

AEM Cloud Service - Sites SPA add additional page properties in sling model response jackson export


Please use this thread to ask the related questions.

Kautuk Sahni

Topics help categorize Community content and increase your ability to discover relevant content.

0 Replies