Get the rendered HTML for an AEM resource, component or page

Adobe Experience Manager | AEM/CQ | Apache Sling

Get the rendered HTML for an AEM resource, component or page

It's easy to retrieve a rendered component by making a GET request. Apache Sling's SlingMainServlet and DefaultGetServlet will process GET requests, take the path's extension into account, and return the rendered resource. The most obvious example of triggering this process is simply typing the component's path into the browser's address bar or making an AJAX call. You can retrieve the HTML markup (or JSON, XML, txt, PDF, etc...) for a component as well as a page if you provide the correct path. After all, they're both just Sling resources.

Trying to get the rendered HTML of a component on the server side is still easy, but requires a little more work. Without knowing the inner workings of Sling, you might use Java's java.net.HttpUrlConnection class to construct and make an HTTP request from within your application to your application.

The better way is to use the SlingRequestProcessor service as the entry point into Sling's process. The processRequest method of the SlingRequestProcessor takes an HttpServletRequest, HttpServletResponse, and Resource Resolver as parameters. The only trick is that you need to provide a request that enables you to set the request path and a response that enables you to get the OutputStream as a String.

AEM provides the RequestResponseFactory where you can easily get such a request and response.



You'll need to provide your own mock request and response in Apache Sling. Fortunately, it already exists. You need the HttpRequest, HttpResponse, and TestServletOutputStream classes.



You will need to include the  org.apache.sling.engine dependency in your pom file. If your bundle resolves but your component remains unsatisfied, make sure sure you've included the package in the Import-Package section of your maven-bundle-plugin.

8 comments

Nate Yolles | December 10, 2015 at 08:21 AM | Reply

Using the SlingRequestProcessor you can get any rendering that your Sling instance provides. For example, you can get the component's JSON rendering if you change the requestPath to something like "/content/myapp/us/en/index.-1.json".

Homer | December 21, 2015 at 12:35 PM | Reply

I am using AEM 5.6.1 and when i use dep finder in system console for org.apache.sling.engine it returns <dependency> <groupId>com.adobe.granite.sling</groupId> <artifactId>org.apache.sling.engine</artifactId> <version>2.2.8-B006</version> <scope>provided</scope> </dependency> But when i tried to add to my pom I am getting build error Could not find artifact com.adobe.granite.sling:org.apache.sling.engine:jar:2.2.8-B006 in adobe (http://repo.adobe.com/nexus/content/groups/public/) Have you encountered this as well? Any workaround you can suggest. Thanks!

radicaledward101 | May 23, 2016 at 04:34 PM | Reply

I was able to get this to work using the following: <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.engine</artifactId> <version>2.4.6</version> <scope>provided</scope> </dependency>. Your version number may be different depending on your version of AEM, but you should chop off the -B### portion. Your build should not need to know the exact build number since the dependency is provided anyway.

Gdubz | June 28, 2016 at 04:11 PM | Reply

When using the AEM implementation, my response is polluted with a bunch of head/meta stuff that a normal page for my project would get. When visiting the resource directly in the browser (with .html at the end), I'm not seeing any of that, just clean <html><head></head><body> /* all the parsys content here */ </body></html>... Am I doing something wrong? I'm guessing the Sling candidate servlet when viewing in browser is different than the SlingRequestProcessor we're using in the code above?

Gdubz | June 28, 2016 at 04:15 PM | Reply

Please disregard this comment, I'm stupid and should probably have doublechecked WHAT I was attempting to resolve before posting. All good now!

APair | July 27, 2016 at 05:37 PM | Reply

Hi, thanks for this sample code :-) I've tried both AemResource and SlingResource methods above, to retrieve rendered HTML of one component, with partial success...: - on author instance, it works perfectly fine! - on publish instance however, part of HTML markup is missing :-(, using both above methods. Mainly, some <a href>s that have some sightly markup in them... To make it even more confusing, doing request to the same path with browser - I see correct and complete output on publish instance... only when calling through above requests methods in java and outputting in servlet, it is missing :-( I continue looking at this problem, but I must say I am out of new ideas on how to debug it... content is there published to publish instance as it renders fine on pages... just when I need it in servlet it is gone... Thanks in advance for dropping me few ideas...

Kartik | May 19, 2017 at 02:22 PM | Reply

Hey, I am also facing the same issue, in publish server, some markups are missing? Did you find anything to fix this issue?

APair | July 27, 2016 at 08:30 PM | Reply

Doh... I've found what is it - got other ideas, that maybe problem is not with the code, not with component, not with sightly/template. And I've found LinkChecker to be removing those links, and only in that specific scenario, DOH, murphy's laws.

Leave a Comment