How to Register Servlets Dynamically in AEM?


Most of the time while working on the project we will have scenarios to dynamically register the servlets with different resource types, selector and extension, etc — registering the same servlet with different resource types, selector, extensions, etc.

Let's assume we have a servlet that is registered with a specific resource type but later we have a requirement to enable the same servlet for a different resource type, one of the common options is modifying the source code to enable the additional resource types. The code change might not be the optimal solution in most cases.

In this tutorial, let us see the simple approach to register the servlets dynamically with different resource types, selectors, and extensions.

The OSGi Metatype Annotations(OSGi Declarative Services Annotations) can be used to register the dynamic servlets.

ObjectClassDefinition — Generate a Meta Type Resource using the annotated type

AttributeDefinition — AttributeDefinition information for the annotated method.

Designate — Generate a Designate element in the Meta Type Resource for an ObjectClassDefinition using the annotated Declarative Services component.

I am creating a servlet with the name DynamicResourceTypeServlet, Created a @ObjectClassDefinition inside the servlet with required AttributeDefinitons with servlet registration 
properties

  @ObjectClassDefinition(name = "DynamicResourceTypeServlet", description = "Resource Types to Enable this Servlet")
  public static @interface Config {
    @AttributeDefinition(name = "Selectors", description = "Standard Sling servlet property")
    String[] sling_servlet_selectors() default {"dynamic"};
    
    @AttributeDefinition(name = "Resource Types", description = "Standard Sling servlet property")
    String[] sling_servlet_resourceTypes() default {""};
    
    @AttributeDefinition(name = "Methods", description = "Standard Sling servlet property")
    String[] sling_servlet_methods() default {"GET"};
    
    @AttributeDefinition(name = "Extensions", description = "Standard Sling servlet property")
    String[] sling_servlet_extensions() default {"html"};
  }


Define a Designate to the servlet to the ObjectClassDefinition.

         @Designate(ocd = DynamicResourceTypeServlet.Config.class)


Deploy the bundle and configure the required resource types, selector, and extensions from ConfigMgr(http://localhost:4503/system/console/configMgr/com.sample.servlets.DynamicResourceTypeServlet)



Now the servlet is registered with configured resource types, selectors, and extensions.

The servlet can be accessed through the below URL’s (the resource type for /content/wknd/us/en is wknd/components/page)

http://localhost:4503/content/wknd/us/en/_jcr_content.dynamic.json (JSON or txt extensions can be accessed only from jcr:content node)



Add the below dependency into the core module to enable the DS annotations

<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.metatype.annotations</artifactId>
<version>1.4.0</version>
<scope>provided</scope>
</dependency>

The bnd-maven-plugin generate the required OSGi meta-type definitions for the annotations during compile time. The dynamic servlet registration is a useful feature that helps to register the servlets dynamically with different resource types, selectors, and extensions.

Feel free to provide your comments.
Source: oraclesoa

How to Register Servlets Dynamically in AEM?