Expand my Community achievements bar.

SOLVED

How to add a selector to a json servlet?

Avatar

Level 5

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:

 

 

@Slf4j
@Component(
        immediate = true,
        service = Servlet.class,
        property = {
                "sling.servlet.methods=get",
                "sling.servlet.resourceTypes=resourceName",
                "sling.servlet.selectors=js",
                "sling.servlet.extensions=json"
        },
        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!!!

 

 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi,

First of all you are accesing the page incorrectly-

 

Please remove jcr:content.

 

And access this link to read about selectors usage.

http://www.aemcq5tutorials.com/tutorials/sling-servlet-in-aem/

 

 

View solution in original post

3 Replies

Avatar

Correct answer by
Community Advisor

Hi,

First of all you are accesing the page incorrectly-

 

Please remove jcr:content.

 

And access this link to read about selectors usage.

http://www.aemcq5tutorials.com/tutorials/sling-servlet-in-aem/

 

 

Avatar

Level 10

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:

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

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(final SlingHttpServletRequest req,
                         final SlingHttpServletResponse resp) throws IOException {
        resp.setContentType("text/plain");
        resp.getWriter().write("Request processed by " + this.getClass().getName());
    }
}

Then you call it like so:

http://localhost:4502/content/demo/us/test/jcr:content.js.json

Here is a screenshot:

Selection_143.png

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 

Avatar

Level 1
Quick Question, in the node structure we dont be having root under the page right? it is present under jcr:content. So for components should it be /content/site/page/jcr:content/root/component ?