Welcome to part 8, in this final part we will review Servlets & Filters in OSGI environment. More precisely we will look at only one case, Sling Servlets & Filters in AEM.
After reading this article, you should be able to
- Create a Sling Servlet.
- Create a Sling Filter.
- Invoke a service from Servlet using reference.
- Be able to use this Servlet Resolver Page.
Sling Framework
Let me remind you that Sling is a REST based web framework build on top of OSGI.
Content-driven that means the framework first finds the content render then determines how to render it basing on the request.
It supports multiple programming languages for rendering scripts.
In this part we will concentrate on Sling Servlets & Filters. We will not discuss rendering pages & Components.
Apache Sling – Custom Servlet
So, just like a generic web application you create your own Servlet & Sling by extending from a base class.
Sling offers two base classes to extend from
- SlingSafeMethodsServlet
- SlingAllMethodsServlet
SlingSafeMethodsServlet means the methods that do not modify data that is GET & HEAD.
SlingAllMethodsServlet methods is for all HTTP methods including POST PUT DELETE etc.
Sling offers various ways of binding servlets. We can use
- Path
- Methods
- Resource Type
- Extension or
- Selectors
Sling Servlet Request
SlingHttpServletRequest and SlingHttpServletResponse are passed to processing methods.
Sling Request provides a few useful methods, here are some of them
- getResource(): It returns the resource that is currently being rendered.
- getResourceResolver(): This is a way to get the resource resolver.
- getRequestPathInfo(): Returns a request path in a sling way that is structure with methods to get selectors, extensions, suffix & so on.
- getRequestParameter(): returns a RequestParameter instance, It is a Sling class that supports getting for eg. An uploaded file as a request parameter.
Let’s see them how the specific of SlingHttpServletRequest, as for SlingHttpServletResponse it does not add important methods.
Sling Servlet Declaration
@Component(service = Servlet.class,
property={"sling.servlet.paths=/services/welcome",
"sling.servlet.paths=/services/hello",
"sling.servlet.resourceTypes=sling/servlet/default", "sling.servlet.methods=" +
HttpConstants.METHOD_GET, "sling.servlet.extensions=csv" })
The way recommended by OSGI 6 is to annotate a Servlet as a Component & specify a servlet as the service interface.
Let me point out that is a difference from how it was done before OSGI release 6, If you work on a long-lasting project, It is possible that you come across an older approach that use sling servlet annotation. That annotation is now deprecated.
Sling Servlet Resolver
Apache Sling Servlets Annotations
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>4.1.0</version>
<inherited>true</inherited>
</plugin>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.servlets.annotations</artifactId>
<version>1.1.0</version>
</dependency>
@Component(service=Servlet.class)
@SlingServletPaths({"/services/stringgen", "/services/stringgenerator"})
@SlingServletResourceTypes(
resourceTypes="sling/servlet/default",
selectors= {"stringgen"}, extensions = "csv")
If you upgrade the maven bundle plugin to 4.1.0 & if you add apache sling servlets annotations library – you will get access to sling servlet annotations.
For eg. there is SlingServletPaths that lets you bind a servlet to a specific paths.
There is also a SlingServletResourceTypes that lets you bind servlet to a combinations of resourceTypes, selectors or extensions.
Sling Filters
Filters are declared as @Component’s with javax.servlet.Filter service interface.
Properties
• sling.filter.scope
• sling.filter.pattern
• service.ranking, service.description, etc
Filter can be configured with Sling Servlets Annotations, if they are available:
@Component(service = Filter.class)
@SlingServletFilter(scope = SlingServletFilterScope.REQUEST,
pattern = "/content/we-retail/us/en/.*")
Let me remind that Filters are part of the Servlet API & used when there is a need to modify the response, transform it somehow or modify request by tempering to this parameters or header or both.
You can create a Filter by implementing Filter interface then you annotate with Component annotation & specify javax.servlet.Filter as the Service class .
Just like with Servlets if SlingServlet annotations are available in your project you can use them to specify filter properties. For that you use SlingServletFilter annotation.
Referencing Services
In OSGI components:
@Reference
private HelloService helloService;
In models:
@Inject
private HelloService helloService;
Let’s remember how OSGI services can be referenced. If you are in an OSGI component & want to inject the Service, you just add the Reference annotation.
If you are in the Model class & here is the Sling specific in the model class, you can use Inject annotation.
Summary
• AEM uses Sling framework that integrates OSGI with the web container.
• Sling allows you to create servlets and filters.
• To create a servlet, extend from one of the Sling servlet classes and annotate it as a @Component with Servlet service interface.
• You can bind a servlet to a path or to a resource type using properties.
• Apache Sling Servlets Annotations offers an improved way of specifying properties, but requires a newer version of the Maven bundle plugin.
• You can check servlet binding in the web console on Servlet Resolver page.
• To create a Sling filter, implement Filter interface and annotate it as a @Component with Filter service interface.
• In the model classes, reference components using @Inject annotation.
Hope you enjoyed this article, I would like to suggest, Kindly watch video below for practical session. So, we reach the end of the OSGI module, Thank you for your attention!