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

Avatar

Avatar

kautuk_sahni

Community Manager

Total Posts

6.0K

Likes

1.1K

Correct Reply

1.1K

Avatar

kautuk_sahni

Community Manager

Total Posts

6.0K

Likes

1.1K

Correct Reply

1.1K
kautuk_sahni
Community Manager

30-03-2021

BlogImage.jpg

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

Abstract

Goal
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...

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;

@Component(
service = Filter.class,
immediate = true,
name = "Expereince AEM Sling Model Response Modifier Servlet Filter",
property = {
Constants.SERVICE_RANKING + ":Integer=-99",
"sling.filter.scope=COMPONENT",
"sling.filter.pattern=.*.model.json"
}
)
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";

@Override
public void init(FilterConfig filterConfig) throws ServletException {
}

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

String uri = slingRequest.getRequestURI();

if(!uri.endsWith(".model.json")){
chain.doFilter(request, response);
return;
}

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;

try{
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{
if(!model.has(CHILDREN)){
return;
}

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){
continue;
}

ValueMap vm = pageContent.getValueMap();

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

if(StringUtils.isNotEmpty(slingVanityPath)){
childData.put(SLING_VANITYPATH_JSON_PROP, slingVanityPath);
}
}
}

@Override
public void destroy() {
}

private class DefaultSlingModelResponseWrapper extends SlingHttpServletResponseWrapper {
private CharArrayWriter writer;

public DefaultSlingModelResponseWrapper (final SlingHttpServletResponse response) {
super(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

Q&A

Please use this thread to ask the related questions.

AEM AEMEBlogSeeding Experience Manager