CQ Tips and Tricks #1 – How to define a SlingServlet [CQ5.5-5.6]

There are many ways to define an OSGI service.
This is the preferred coding style for CQ version 5.5-5.6 that we follow on our team.

Registering the servlet by path

import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;

import javax.servlet.ServletException;
import java.io.IOException;

@SlingServlet(
    paths={"/services/unicom/v1/"}
)
@Properties({
    @Property(name="service.pid", value="com.adobe.unicom.v1.servlets.OmnnitureLoggingServlet",propertyPrivate=false),
    @Property(name="service.description",value="Omniture service call logging servlet", propertyPrivate=false),
    @Property(name="service.vendor",value="Adobe Systems Incorporated - Adobe@Adobe Team", propertyPrivate=false)
})
public class OmnnitureLoggingServlet extends SlingAllMethodsServlet
{
    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException
    {
        //Do something fun here
    }

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException
    {
        //Do something fun here
    }
}

OR  registering the servlet by resource type and extension

import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;

import javax.servlet.ServletException;
import java.io.IOException;

@SlingServlet(
    resourceTypes = {"rep:User"},
    methods = {"GET", "POST"}
)
@Properties({
    @Property(name="service.pid", value="com.adobe.unicom.v1.servlets.OmnnitureLoggingServlet",propertyPrivate=false),
    @Property(name="service.description",value="Omniture service call logging servlet", propertyPrivate=false),
    @Property(name="service.vendor",value="Adobe Systems Incorporated - Adobe@Adobe Team", propertyPrivate=false)
})
public class OmnnitureLoggingServlet extends SlingAllMethodsServlet
{
    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException
    {
        //Do something fun here
    }

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException
    {
        //Do something fun here
    }
}

To handle all requests and filter on selector you can change the example above to read something like this.

import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;

import javax.servlet.ServletException;
import java.io.IOException;

@SlingServlet(
    resourceTypes = {"sling/servlet/default"},
    methods = {"GET"},
    selectors = {"report"},
    extensions = {"json"}
)
@Properties({
    @Property(name="service.pid", value="com.adobe.unicom.v1.servlets.OmnnitureLoggingServlet",propertyPrivate=false),
    @Property(name="service.description",value="Omniture service call logging servlet", propertyPrivate=false),
    @Property(name="service.vendor",value="Adobe Systems Incorporated - Adobe@Adobe Team", propertyPrivate=false)
})
public class OmnnitureLoggingServlet extends SlingAllMethodsServlet
{
........

For more details on the Felix Annotations see

2 Responses to CQ Tips and Tricks #1 – How to define a SlingServlet [CQ5.5-5.6]

  1. It seems to me that the paths property of the @SlingServlet annotation overrides the resourceTypes and methods properties:

    The javadoc for the SlingServlet annotation [0] says that resourceTypes and paths are converted to sling.servlet.resourceTypes and sling.servlet.paths properties, respectively.

    The Sling documentation [1] states that if a value for sling.servlet.paths is specified, the resourceTypes property and the methods property are ignored.

    regards,
    scott

    [0] http://svn.apache.org/repos/asf/felix/trunk/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/sling/SlingServlet.java
    [1] http://sling.apache.org/site/servlets.html

    • dbenge says:

      Thanks for the correction. I missed that. I have updated the examples with the corrections you outlined.