March 29, 2020
Estimated Post Reading Time ~

Apache Sling : Servlets and Scripts in AEM 6.3

Sling Servlets is one of the very useful concepts in AEM. How much we know and use it, It has a lot more to know about it. So In this blog, I will start with basics and will walk you through all the options and varieties of Sling Servlets with hands-on examples.

Servlet Registration
To register a servlet the following properties play a vital role.

1. sling.servlet.paths: A list of absolute paths under which the servlet is accessible as a Resource. The property value must either be a single String, an array of Strings or a Vector of Strings.

A servlet using this property might be ignored unless its path is included in the Execution Paths (servletresolver.paths) configuration(Apache Sling Servlet/Script Resolver and Error Handler) setting of the SlingServletResolver service.

@Component(service = Servlet.class,
property = {
Constants.SERVICE_DESCRIPTION + "=Simple Demo Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_GET,
"sling.servlet.paths=" + "/bin/servlet",
"sling.servlet.extensions=" + "sample",
})
public class ResolveServletUsingPath extends SlingSafeMethodsServlet {
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
}

}

This Servlet service registered with these properties is registered under this path: /bin/servlet

Note: In the above example, Servlet is only registered by path, so the registration properties sling.servlet.method, sling.servlet.extension has been ignored.

2. sling.servlet.resourceTypes:The resource type(s) supported by the servlet. The property value must either be a single String, an array of Strings or a Vector of Strings.

Note:Either this property(sling.servlet.resourceTypes) or the sling.servlet.paths property must be set, or the servlet is ignored. If both are set, the servlet is registered using both ways.


Fig - Register the servlet using the resource type

@Component(service=Servlet.class,
property={
Constants.SERVICE_DESCRIPTION + "=Simple Demo Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_GET,
"sling.servlet.resourceTypes="+ "community-components/components/componentpage",
"sling.servlet.extensions=" + "sample",
})
public class MyServlet extends SlingSafeMethodsServlet {

@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)throws IOException
{

}
}


3. sling.servlet.selectors: The request URL selectors supported by the servlet. The selectors must be configured as they would be specified in the URL that is a list of dot-separated strings such as print.a4. 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.

@Component(service=Servlet.class,
property={
Constants.SERVICE_DESCRIPTION + "=Simple Demo Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_GET,
"sling.servlet.resourceTypes="+ "community-components/components/componentpage",
"sling.servlet.selectors="+"img",
"sling.servlet.selectors="+"tab",
})
public class MyServlet extends SlingSafeMethodsServlet {

@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)throws IOException
{
}
}


The request can be:
http://localhost:4502/content/community-components/en/tagcloud/jcr:content.img.json
http://localhost:4502/content/community-components/en/tagcloud/jcr:content.tab.json

4. 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.

5. sling.servlet.methods: The request methods supported by the servlet. This property is only considered for the registration with sling.servlet.resourceTypes. If this property is missing, the value defaults to GET and HEAD, regardless of which methods are actually implemented/handled by the servlet.

6. sling.servlet.prefix: The prefix or numeric index to make relative paths absolute. If the value of this property is a number (int), it defines the index of the search path entries from the resource resolver to be used as the prefix.

The defined search path is used as a prefix to mount this servlet. The number can be -1 which always points to the last search entry. If the specified value is higher than than the highest index of the search paths, the last entry is used. The index starts at 0. If the value of this property is a string and parseable as a number, the value is treated as if it would be a number. If this property is not specified, it defaults to the default configuration of the sling servlet resolver.
So if:

  • prefix=0 or prefix=/apps/, then it will accept the default request(relative path of resourceType) and the resourceType starts with “/apps”.because /apps is the first index of search path entry.
  • prefix=1 or prefix =/libs/ then it will accept the default request(relative path of resourceType) and the resourceType starts with “/libs”
  • the default scenario is prefix=-1, then it will accept the default request(relative path of resourceType) and the resourceType starts with “/libs” because /libs is last search entry.
Note: Binding resources by paths is discouraged.
Always try to register servlets using resourceTypes in place of paths. You can use selectors and extensions to uniquely identify a servlet.

@Component(service=Servlet.class,
property={
Constants.SERVICE_DESCRIPTION + "=Simple Demo Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_GET,
"sling.servlet.resourceTypes="+ "sling/servlet/default",
"sling.servlet.selectors="+ "data",
"sling.servlet.extensions="+ "sample"

})
public class MyServlet extends SlingSafeMethodsServlet {

@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)throws IOException
{
}
}

The request can be:
http://{server host:server port}/{any path}.data.json

The value of “sling.servlet.resourceTypes” is “sling/servlet/default” to handle all kinds of requests having any path. We can also consider it as a default resourceType.



There is an OSGi Configuration named Apache Sling Servlet/Script Resolver and Error Handler in the Felix console

Fig - Servlet/Script resolver configuration

There are four options in this configuration:
Servlet Registration Root Path: If the servlet doesn’t have a prefix, the value of prefix needs to be picked from this configuration.
Cache Size: This property configures the size of the cache used for script resolution. To see the scripts which are being cached
Go to the Felix console.
Go to Sling->Script Cache Status

Fig - Check Sling Cache Status in Felix console

The cache of script resolution can be seen here:


Fig - Check Cached Script in Felix console

Execution Paths: The paths to search for executable scripts. This configuration means: All the paths start with the paths they have provided will be allowed.
If no path is specified, this will be treated like (/=root) which allows all scripts. If we add one path without ending with /, then it means it will only allow an exact path.

Default Extension: The list of extensions for which the default behavior will be used. There is a sling resolver test provided by Felix console where we can check that a particular request resolves to which servlet.

Go to Felix console.
Go to Sling-> Sling Servlet Resolver

Fig - Servlet Resolver option in felix


Fig - Check servlet is resolving or not


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.