AEM Sling Servlet Complete Guide
A complete guide to AEM Sling Servlets, including configuration, lifecycle, types, and real-world examples.

After reading this article, you should understand:
- What is Sling Servlet?
- Java Servlet lifecycle
- Lifecycle of an AEM Servlet
- The key differences between a Java Servlet and an AEM Servlet
- Sling Servlet configuration and constraints
- Restrictions on Sling Servlets
- Types of Sling Servlets
- Step-by-step flow and architecture of Sling Servlets
- Servlet registration
- Servlet annotation properties
- Resource type vs path-based servlets
- Real-time examples for creating path-based and resource-type servlets
What is a Servlet?
A servlet is a Java class designed to enhance server functionality by handling client requests and generating responses. It acts as a bridge between the web server and backend logic, allowing applications to produce dynamic content.
Java Servlet Lifecycle

Loading and Instantiation
- The servlet container loads the servlet class when the application starts or when the servlet is accessed for the first time.
- The servlet class is loaded into memory.
- An instance of the servlet is created using the default no-argument constructor.
Initialization (init method)
- The
init()method is called once after the servlet instance is created. - The servlet is initialized with configuration data from
web.xmlor annotations. - This is where resources such as database connections are typically set up.
Request Handling (service method)
- For every client request, the container invokes the
service()method. - The
service()method determines the request type (GET, POST, etc.) and dispatches it todoGet(),doPost(), etc. - The servlet processes the request and generates a response.
Destruction (destroy method)
- When the servlet container shuts down or the servlet is removed,
destroy()is called. - Resources are released and cleanup operations are performed.
Lifecycle of an AEM Servlet
AEM servlets are managed through the OSGi framework and Sling. They are built to work with AEM components and the JCR repository.

Component Declaration
- A servlet is declared as an OSGi component using annotations like
@Component,@Service,@SlingServletPaths, and@SlingServletResourceTypes. - The OSGi container discovers and registers the servlet as a service.
- The servlet is registered based on resource type, path, or selector.
Dependency Injection
- Before initialization, OSGi injects required dependencies into the servlet.
- Services such as
ResourceResolverFactoryorSlingHttpServletRequestcan be injected. - This allows the servlet to interact with AEM’s resource tree and JCR.
Activation (@Activate method)
- The servlet becomes active once its dependencies are satisfied.
- The optional
@Activatemethod can initialize configuration or resources.
Request Handling
- Sling dispatches HTTP requests to the servlet based on path, resource type, or selector.
- The servlet processes the request in
doGet()ordoPost(). - It interacts with the resource tree and JCR to render content or perform backend logic.
Deactivation (@Deactivate method)
- When the bundle stops or the servlet is unregistered, the servlet is deactivated.
- Resources created during activation are released.
Key Differences Between Java Servlets and AEM Servlets

- Java Servlets are general-purpose server-side components for web applications.
- AEM Servlets are OSGi-managed Sling components designed for AEM and JCR content.
- AEM Servlets integrate with Sling resolver and AEM content models.
- AEM Servlets use annotations and service properties for registration.
What are Sling Servlets?
- Sling Servlets are server-side components for Sling-based applications that handle HTTP requests and generate responses.
- They are registered as OSGi services, making them modular and dynamically manageable.
- Sling is a REST-based framework that maps JCR content via URLs.
- Sling Servlets use this framework to process dynamic content and implement custom AEM logic.

Sling Servlet Configuration and Constraints
Mandatory Properties
- Either
sling.servlet.pathsorsling.servlet.resourceTypesmust be set. - If neither is set, the servlet service is ignored.
Handling Conflicts
- If both
sling.servlet.pathsandsling.servlet.resourceTypesare set, the servlet is registered by both methods.
Property Precedence
- If
sling.servlet.pathsis set, othersling.servlet.*properties are ignored for path-based registration.
Resource Provider Registration
- If
sling.servlet.pathsis not set, Sling registers the servlet for every combination of resource type, selector, extension, and method.
Types of Sling Servlets
There are two main servlet types in Sling, each designed for different request methods.
SlingSafeMethodsServlet
- Use this servlet for read-only HTTP methods: GET, HEAD, and OPTIONS.
- It extends the basic
HttpServletbehavior with Sling-specific handling. - Ideal for fetching data without modifying server state.
SlingAllMethodsServlet
- Extends
SlingSafeMethodsServletand supports POST, PUT, DELETE, and other methods. - Use it when you need both read and write operations.
Step-by-Step Flow and Architecture of Sling Servlets

Step 1: Request from Web Browser
- A browser sends a request to the server via HTTP or HTTPS.
- This may be a GET to retrieve content or a POST to submit data.
Step 2: Sling Intercepts the Request
- Sling recognizes the request as AEM-related and applies URL mapping.
- It routes the request to the correct servlet or resource.
Step 3: Resolve the Resource
- Sling resolves resources using path-based or resource-type mappings.
Path-Based Mapping
- The servlet is registered with
sling.servlet.pathsor@SlingServletPaths. - Example:
/bin/examplemaps directly to a servlet.
Resource Type Mapping
- The servlet is registered with
sling.servlet.resourceTypesor@SlingServletResourceTypes. - Example: a request to
/content/examplematches a resource type such asexample/components/content.
Step 4: Match the Servlet
- Sling Servlet Resolver finds the servlet by path or resource type.
Step 5: Dispatcher Caching
- Dispatcher checks if the response is cached before forwarding to AEM.
- If cached, Dispatcher returns the cached response.
- Otherwise, it forwards the request to AEM.
Step 6: Servlet Processing
- The servlet processes the request, validates data, and applies business logic.
- It may save or retrieve content from JCR.
Step 7: Response Format
- The servlet returns responses in JSON, XML, HTML, or binary formats.
Servlet Registration
@Component
- In AEM,
@Componentregisters the servlet as an OSGi service. - OSGi treats the servlet as a managed service available at runtime.
A Sling Servlet Can Be Registered in Two Ways
Using Resource Types
- Use the node’s
sling:resourceTypeto map a servlet to a resource type. - The servlet executes when the resource type matches.
Using Paths
- Register the servlet directly with a path using
sling.servlet.paths. - The servlet executes when the exact URL is requested.
Important Servlet Annotation Properties
sling.servlet.paths: exact servlet access path.sling.servlet.resourceTypes: resource types that trigger the servlet.sling.servlet.methods: HTTP methods such as GET, POST, DELETE.sling.servlet.selectors: additional selector-based request parameters.sling.servlet.extensions: file extensions liketxt,json, orhtml.
Resource Type vs Path-Based Servlets

Resource Type-Based Servlets
- More secure because Sling enforces resource permissions.
- The servlet executes after the resource is resolved.
- Easier to manage within AEM’s access control model.
Path-Based Servlets
- Mapped to a specific path rather than a resource type.
- Less flexible with suffixes and selectors.
- Requires exact path definitions.
Real-Time Example: Path-Based Servlet
Requirement
- Dynamically create new pages in AEM under a parent path.
- Use a predefined template.
- Provide page name, title, and parent path as input.
Approach
- Use a servlet to handle HTTP requests and create pages dynamically.
- Use
ResourceResolverandPageManager. - Validate input and clean up resources properly.
Example Code
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.Page;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.Servlet;
import java.io.IOException;
@Component(service = Servlet.class,
property = {
Constants.SERVICE_DESCRIPTION + "=Create Page Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_GET,
"sling.servlet.paths=" + "/bin/createDynamicPages"
})
public class CreateDynamicPages extends SlingAllMethodsServlet {
private static final Logger log = LoggerFactory.getLogger(CreateDynamicPages.class);
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws IOException {
log.info("----------< Executing Create Page Servlet >----------");
try (ResourceResolver resourceResolver = request.getResourceResolver()) {
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
if (pageManager == null) {
log.error("PageManager is not available");
response.getWriter().write("Error: PageManager is not available");
return;
}
String parentPath = request.getParameter("parentPath");
String pageName = request.getParameter("pageName");
String templatePath = "/conf/aem-debugcode/Generic/settings/wcm/templates/generic-template";
String pageTitle = request.getParameter("pageTitle");
if (parentPath == null || pageName == null || pageTitle == null) {
response.getWriter().write("Error: Missing required parameters");
return;
}
Page newPage = pageManager.create(parentPath, pageName, templatePath, pageTitle);
if (newPage != null) {
log.info("Page created successfully: {}", newPage.getPath());
response.getWriter().write("Page created successfully: " + newPage.getPath());
} else {
log.error("Failed to create page");
response.getWriter().write("Error: Failed to create page");
}
} catch (Exception e) {
log.error("Error while creating page: {}", e.getMessage(), e);
response.getWriter().write("Error: " + e.getMessage());
}
}
}
Example URL
http://localhost:4502/bin/createDynamicPages?parentPath=/content/aem-debugcode/us/en&pageTitle=LandingPage&pageName=landPage
Real-Time Example: Resource Type Servlet
Requirement
- Dynamically fetch and display child pages for a specific parent page.
- Accept
pagePathas input. - Default to
/content/aem-debugcode/us/enwhen no parameter is provided. - Return child page titles and paths in JSON or plain text.
Example Code
import java.io.IOException;
import java.util.Iterator;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServletResourceTypes;
import org.osgi.service.component.annotations.Component;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
@Component(service = Servlet.class)
@SlingServletResourceTypes(resourceTypes = "aem-debugcode/components/page",
selectors = "list", extensions = {"txt", "json"})
public class AccessComponentsServlet extends SlingSafeMethodsServlet {
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
ResourceResolver rr = request.getResourceResolver();
String pagePath = request.getParameter("pagePath");
if (pagePath == null) {
pagePath = "/content/aem-debugcode/us/en";
}
PageManager pm = rr.adaptTo(PageManager.class);
Page page = pm.getPage(pagePath);
Iterator<Page> childPages = page.listChildren();
JsonArrayBuilder jsonObj = Json.createArrayBuilder();
while (childPages.hasNext()) {
JsonObjectBuilder jsonBuilder = Json.createObjectBuilder();
Page selectedPage = childPages.next();
jsonBuilder.add("title", selectedPage.getTitle());
jsonBuilder.add("path", selectedPage.getPath());
jsonObj.add(jsonBuilder);
}
response.getWriter().write(jsonObj.build().toString());
}
}
Example URL
http://localhost:4502/content/aem-debugcode/us/en/jcr:content.list.txt
Summary
This guide covers the architecture, lifecycle, registration, and implementation patterns for AEM Sling Servlets. Use the examples above to create dynamic page creation servlets and resource-type servlets that return structured results.