A Real-World Example Using the Resource API
So far, we’ve covered the basics of ResourceResolver, Resource, and the Resource API.
We’ve seen how to get a resource, access its properties, traverse children, and adapt it to other objects.
But theory is one thing. Let’s see how all this works in a real-world scenario.
1. Requirement
We have a DAM folder /content/dam/my-project-site/documents
where we upload a lot of files.
We want to expose an endpoint (a simple servlet) that returns a list of all PDFs uploaded inside that folder, including PDFs in any nested subfolders.
But we don’t want it hardcoded for just one folder.
I want to know what PDFs exist in a certain folder and subfolder—maybe for debugging or to feed another system.
The folder path should be dynamic, passed as a query parameter, so we can check different folders without changing code.
We’ll solve this using pure Resource API.
2. Approach
Before jumping into code, let’s plan it step by step
- We’ll write a Sling Servlet exposed at
/bin/list-pdfs
- The servlet will accept a
path
parameter to specify which folder to search in - The servlet will use
request.getResourceResolver()
Tip: We’re using the request’s
ResourceResolver
, so no service user or permissions setup is needed — this works only for authenticated users who have access to the given DAM path.
- We’ll fetch the folder as a Resource using
getResource(folderPath)
- We’ll use a recursive function to traverse all child folders (not just direct children)
- Inside each folder, we’ll check for
dam:Asset
resources - We’ll filter only PDFs (by checking mimeType)
- And finally, print the PDF paths in the response
3. Implementation
So, with that plan in mind, I started coding the servlet.
Here’s the code I wrote first
package com.debug.code.core.servlets;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.*;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;
import javax.servlet.Servlet;
import java.io.IOException;
import java.util.Iterator;
@Component(service = Servlet.class, property = {
"sling.servlet.paths=/bin/list-pdfs"
})
public class ListPdfAssetsServlet extends SlingAllMethodsServlet {
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
ResourceResolver resourceResolver = request.getResourceResolver();
String folderPath = request.getParameter("path");
if (folderPath == null || folderPath.isEmpty()) {
response.getWriter().println("Please provide a valid folder path using ?path= parameter.");
return;
}
Resource damFolder = resourceResolver.getResource(folderPath);
if (damFolder != null) {
response.setContentType("text/plain");
listPdfsRecursively(damFolder, response);
} else {
response.getWriter().println("Folder not found at path: " + folderPath);
}
}
private void listPdfsRecursively(Resource folder, SlingHttpServletResponse response) throws IOException {
Iterator<Resource> children = folder.listChildren();
while (children.hasNext()) {
Resource child = children.next();
if (child.isResourceType("dam:Asset")) {
Resource metadata = child.getChild("jcr:content/metadata");
if (metadata != null) {
ValueMap properties = metadata.getValueMap();
String mimeType = properties.get("dc:format", String.class);
if ("application/pdf".equals(mimeType)) {
response.getWriter().println("PDF: " + child.getPath());
}
}
} else if (child.isResourceType("sling:OrderedFolder") || child.isResourceType("sling:Folder")) {
listPdfsRecursively(child, response);
}
}
}
}
4. Code walkthrough
We define a Sling Servlet exposed at /bin/list-pdfs
@Component(service = Servlet.class, property = {
"sling.servlet.paths=/bin/list-pdfs"
})
This makes the servlet accessible at /bin/list-pdfs
without registering under a resource type.
In doGet()
We get the folder path from the query param
String folderPath = request.getParameter("path");
We check if it’s missing and send an error message if so.
We get the resource for that folder
Resource damFolder = resourceResolver.getResource(folderPath);
If it doesn’t exist, we return an error. Otherwise, we start recursive traversal.
We traverse recursively
private void listPdfsRecursively(Resource folder, SlingHttpServletResponse response) throws IOException { ... }
Inside this method
For each child
- If it’s
dam:Asset
, checkdc:format
(MIME type) - If it’s a folder, recursively call
listPdfsRecursively()
5. Deployment
Once your Servlet Code is ready, you need to deploy it on your Local Machine.
To build and deploy only the core module in AEM, you can use the following command:
mvn clean install -PautoInstallBundle
If you want to skip tests during the build, you can add the -DskipTests=true
flag:
mvn clean install -PautoInstallBundle -DskipTests=true
Once Deployed, Go and Hit this URL:
http://localhost:4502/bin/list-pdfs?path=/content/dam/aem-debugcode
6. Example output:
We’re just printing plain text for simplicity. In real apps, you can easily change the response to JSON.
PDF: /content/dam/my-site/documents/report.pdf
PDF: /content/dam/my-site/documents/2024/march/summary.pdf
PDF: /content/dam/my-site/documents/2024/april/plan.pdf
Every great discussion starts with a simple thought! If you enjoyed this article, found it useful, or have any questions, let’s talk! I’d love to hear from you.
For more updates, tips, and engaging conversations, connect with me on Medium, LinkedIn, and RealCodeWorks. Let’s keep learning together! 🚀✨
Thank you 🙏 !