AEM Developer Series
- Day 00: AEM Developer Series
- Day 01: Introduction to AEM
- Day 02: AEM Architecture
- Day 03: Setting up AEM Development Environment
- Day 04: Developing First OSGi Bundle
- Day 05: Working with Sling Servlets in AEM
- Day 06: Playing with Sling Post Servlet
- Day 07: Creating your first component in AEM
- Day 08: Dueling with JavaScript Use API
- Day 09: Dueling with Java User API
- Day 10: Getting to know Sling Models
- Day 11: Client Libraries in Action
- Day 12: Creating your custom OSGi Configuration
- Day 13: Schedulers in AEM
- Day 14: Eventing in AEM
- Day 15: Custom Workflows in AEM
- Day 16: Creating JMX Beans in AEM
- Day 17: Working with QueryBuilder API
- Day 18: Working with Granite Datasources in AEM
- Day 19: Replication API in Action
- Day 20: Working with Users and Groups in AEM
All servlets must implement the Servlet interface, which defines life-cycle methods. When implementing a generic service, we can use or extend the GenericServlet class provided with the Java Servlet API. The HttpServlet class provides methods, such as doGet() and doPost(), for handling HTTP-specific services.
Sling Servlets
In Sling, servlets can be registered as services. Whenever you create an AEM Multimodule Project (How? see here) using maven archetype 14, the default template for a Sling Servlet is generated as follows -
Let us discuss its parts one by one- @Component annotation - This OSGi annotation signifies that the class is a Service component and is not processed at runtime by a Service Component Runtime (SCR) implementation. It must be processed by tools and used to add a Component Description to the bundle.
- service property - This signifies the types under which to register this Component as a service. In our case, the component is registered under the Servlet type.
- Constants.SERVICE_DESCRIPTION - Defines standard names for the OSGi environment system properties, service properties, and Manifest header attribute keys. In our case, we are defining the description of our servlet.
- sling.servlet.methods - Defines which methods this servlet will use. In our case, we are using the HTTP GET method.
- sling.servlet.resourceTypes - This property defines how are we accessing the servlet. There are two ways - via resource types and via paths. We will discuss this in the next section.
- sling.servlet.extensions - The request URL extensions supported by the servlet for requests. The property value must either be a single String, an array of Strings or a Vector of Strings. This property is only considered for the registration with sling.servlet.resourceTypes.
Servlet Registration
A SlingServletResolver listens for Servlet services and - given the correct service registration properties - provides the servlets as resources in the (virtual) resource tree. Such servlets are provided as ServletResource instances which adapt to the javax.servlet.Servlet class.
For a Servlet registered as an OSGi service to be used by the Sling Servlet Resolver, either one or both of the sling.servlet.paths or the sling.servlet.resourceTypes service reference properties must be set. If neither is set, the Servlet service is ignored.
A Sling servlet can be registered in two ways -
- Using Resource Types - Using this way, we use the sling:resourceType property of the node. For this, we need to hit the path in the browser for which the sling:resourceType is the given one.
- Using Paths - Using this way, we can directly use the path specified in the request and our servlet will be executed.
Registering a servlet via a path is relatively easier than registering it via a resource type but it is still recommended to use resource types instead of paths. Below are the reasons why -
- If we use paths, then we need to be extra careful as we do not want to give any path randomly. The servlets cannot be access-controlled using the default JCR ACLs.
- No suffix handling in the path bound servlets.
- We also need to specify the paths to the servlet consumers and change in the path can have a serious impact.
Types of Servlets
There are two types of servlets in Sling which are nothing but the classes we need to extend while creating our servlet.
- SlingSafeMethodsServlet - If we want to use only the read-only methods then we use this. This base class is actually just a better implementation of the Servlet API HttpServlet class which accounts for extensibility. So extensions of this class have great control over what methods to overwrite. It supports GET, HEAD, OPTIONS etc methods.
- SlingAllMethodsServlet - If we want to use methods that write as well, then we use this. This class extends the SlingSafeMethodsServlet by support for the POST, PUT and DELETE methods.
Sling Servlet Example
In this section, we will be creating our custom Sling Servlet to fetch the JSON data from a RESTful webservice.
As you can see that we are using Network.java and AppConstants.java in the code. This you can find in my previous post.
- If we use paths, then we need to be extra careful as we do not want to give any path randomly. The servlets cannot be access-controlled using the default JCR ACLs.
- No suffix handling in the path bound servlets.
- We also need to specify the paths to the servlet consumers and change in the path can have a serious impact.
Types of Servlets
There are two types of servlets in Sling which are nothing but the classes we need to extend while creating our servlet.
- SlingSafeMethodsServlet - If we want to use only the read-only methods then we use this. This base class is actually just a better implementation of the Servlet API HttpServlet class which accounts for extensibility. So extensions of this class have great control over what methods to overwrite. It supports GET, HEAD, OPTIONS etc methods.
- SlingAllMethodsServlet - If we want to use methods that write as well, then we use this. This class extends the SlingSafeMethodsServlet by support for the POST, PUT and DELETE methods.
Sling Servlet Example
After deploying the code on your AEM server (how? see here), hit the URL http://<host>:<port>/bin/readjson. You will see JSON string returned on your screen.
Conclusion
Congratulations!! 🙋we have created our first servlet. You can find the complete code at my GitHub.
Newbie question, we are doing the same thing with OSGI and sling servlet then what exactly is the difference between both of them
ReplyDeleteThanks
Hi Shiva,
DeleteAs you can see that JSONServlet class is annotated with @Component. A component is the fundamental unit of code in OSGi. Thus, a Sling Servlet is also an OSGi component (in fact, every class in OSGi is a component, or used by a component).
The concept of Servlets is not specific to OSGi. In Java, Let's say if you want to implement sever-side functionality that deals with HTTP, then we extend our class from HttpServlet In OSGi, we achieve this using Sling Servlets (which extends HttpServlet).
In a nutshell, a Sling Servlet is also an OSGi component of service type Servlet (see the parameter in the @Component annotation - "service=Servlet.class").
I hope this is helpful.
Thank you for taking your time to explain, helped a lot
DeleteHey what is difference between regular servlet and sling servlet
ReplyDeleteJust like the normal HttpServlet, SlingSafeMethodsServlets extends GenericServlet class. It is just the better implementation of HttpServlet and in SlingSafeMethodsServlet, data can only be read. For data modification, we use SlingAllMethodsServlet which extends SlingSafeMethodsServlet.
DeleteSee more at - https://sling.apache.org/apidocs/sling5/org/apache/sling/api/servlets/SlingSafeMethodsServlet.html
Tx Anirudh
ReplyDeleteVery well structured tutorial. Things I'd consider adding (perhaps these are covered later in the series):
1. Alternative implementation using ResourceType
2. How to check the implementation class of a servlet on Felix Console (/system/console/servletresolver)
But once again, really appreciate the effort you've put in here!