Register Sling Servet in Adobe Experience Manager

In Adobe Experience Manager (AEM), a Sling servlet can be used for handling some RESTful request-responses ajax call. It is written in Java programming language and it can be registered as OSGi (Open Services Gateway Initiative) services. In order to trigger the script, there are two ways to register it: 1. By Path or 2. By resourcesTypes and I will explain in details below:

1. Register by Path

Say for example, you want to do a form POST request to the path /bin/payment from client side to the sling servlet class, you may use the annotation below:

[@SlingServlet](http://twitter.com/SlingServlet) {
  metatype = true,
  methods = { "POST" },
  paths = "/bin/payment"
}
public class YourServlet extends SlingSafeMethodsServlet {

   [@Override](http://twitter.com/Override)
   protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throw ServletException {
       // do your work here
   }
}

Then when there is a POST request to the http://localhost:4502/bin/payment, the above servlet would be trigger and the doPost method is invoked.

The prerequisites is that you have the local AEM up and running at the port 4502 and installed the bundle module via the maven bundle plugin. You may check the bundle is installed by navigating to the http://localhost:4502/system/console/bundles. If not, you may also manually upload the jar to install.

In case you hit forbidden error and cannot serve request to /bin/payment in /libs/sling/servlet/errorhandler/default.jsp, you may need the solution below:

  1. Go to http://localhost:4502/system/console/configMgr

  2. Search for ‘Apache Slign Referrer Filter’

  3. Remove POST method from the filter. Then you should be able to trigger the POST method from anywhere.

  4. Also find Adobe Granite CSRF Filter

  5. Remove POST from Filter methods

  6. Save and test the servlet again.

Then the servlet should be able to trigger as expected.

2. Register by resourceType

In order to avoid above trouble, the better way would be register by resourceType. Refractor the above servlet to below:

[@SlingServlet](http://twitter.com/SlingServlet) {
  metatype = true,
  methods = { "POST" },
  resourceTypes = "services/payment"
}
public class YourServlet extends SlingSafeMethodsServlet {

   [@Override](http://twitter.com/Override)
   protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throw ServletException {
       // do your work here
   }
}

Then you would also need to create a page to trigger this resource.

  1. Go to CRDXE Lite at http://localhost:4502/crx/de/index.jsp

  2. Then inside /content folder, create a page, say for example we create a page http://localhost:4502/content/submitPage.html

  3. In the resourceType properties, put the value services/payment or anything matched with your servlet above.

  4. Save and test the POST request to http://localhost:4502/content/submitPage.html, it should work.

Extra tips: you can also test via the Apach Sling Resource Reolver to see if the servlet was registered successfully in http://localhost:4502/system/console/jcrresolver

Let me know in the comment below if you have any questions.

Originally published at https://victorleungtw.com on January 29, 2020.