How to add a selector to a json servlet?



Hi guys,

I'm working in AEM 6.3 and writing a servlet that will be producing json data. I'm using the following annotation based configuration:



        immediate = true,
        service = Servlet.class,
        property = {
        configurationPid = "com.package.ServletName"



I have a resource of sling:resourceType at /content/path/jcr:content and when I place a GET request to http://localhost:4502/content/path/jcr:content.js.json, I expect to see the results of my servlet, but I see this:


Invalid recursion selector value 'js'
Cannot serve request to /content/path/jcr:content.js.json on this server


If I change my servlet to hardcode the path using sling.servlet.paths, it works, but I don't want to hardcode the path.


Any help would be appreciated.I would also appreciate any general explanations as to how AEM prioritizes matching on path, resourceType, selector, and extension when choosing which servlet to delegate to.


Thanks much!!!



Accepted Solutions (1)

Accepted Solutions (1)

Answers (1)

Answers (1)




Hello @jkpanera,

I'm sorry but I find this line confusing: "I have a resource of sling:resourceType at /content/path/jcr:content". sling:resourceType is a property, its the value of that property which will dictate which servlet is called, so what sling:resourceType that you want to render?

Since the resource in question has a jcr:content child, I'm assuming its a page? In that case, here is some working code:

        immediate = true,
        service = Servlet.class,
        property = {
                "sling.servlet.methods=" + HttpConstants.METHOD_GET,
                "sling.servlet.resourceTypes=" + "demo/components/structure/page",
                "sling.servlet.extensions=" + "json"
@ServiceDescription("JS JSON Servlet")
public class SimpleServlet extends SlingSafeMethodsServlet {

    private static final long serialVersionUID = 1L;

    protected void doGet(final SlingHttpServletRequest req,
                         final SlingHttpServletResponse resp) throws IOException {
        resp.getWriter().write("Request processed by " + this.getClass().getName());

Then you call it like so:


Here is a screenshot:


In order to call a servlet which is mapped to a resource type, you must provide a path to the JCR resource which a sling:resourceType property. For example:

  • If the resource is a component at /content/site/page/root/component, then the request should be to /content/site/page/root/component.js.json because that's the node which has a sling:resourceType property.
  • If the resource is a page at /content/site/page, then the request should be to /content/site/page/jcr:content.js.json because the jcr:content child node is the one with the sling:resourceType property

Hope this helps 🙂