POST from 3rd party client to SlingServlet registered using resourceTypes | Community
Skip to main content
mpalme1
Level 3
October 14, 2020
Solved

POST from 3rd party client to SlingServlet registered using resourceTypes

  • October 14, 2020
  • 1 reply
  • 2211 views

I am trying to create a servlet, registered using resourceType, that can accept an HTTP POST from a client external to the AEM site. Here's is my current code:

 

 

package com.ab.mysite.core.servlets; import org.osgi.service.component.annotations.Component; import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletException; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.servlets.SlingAllMethodsServlet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component( service=Servlet.class, property= { "sling.servlet.resourceTypes="+ "mysite/components/structure/page", "sling.servlet.selectors=" + "biosync", "sling.servlet.extensions=" + "html", "sling.servlet.methods="+"POST", "sling.servlet.methods="+"GET" } ) public class BioSyncServlet extends SlingAllMethodsServlet { private static final long serialVersionUID = 1L; private static final Logger log = LoggerFactory.getLogger(BioSyncServlet.class); @Override protected void doPost( SlingHttpServletRequest request, SlingHttpServletResponse response) { try { addCorsHeader(response); response.setContentType("text/plain"); response.getWriter().write(getResponse(request)); response.getWriter().close(); } catch (Exception ex) { log.error(ex.getMessage()); } } @Override protected void doGet( SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException, ServletException { try { addCorsHeader(response); response.setContentType("text/plain"); response.getWriter().write(getResponse(request)); response.getWriter().close(); } catch (Exception ex) { log.error(ex.getMessage()); } } private void addCorsHeader(SlingHttpServletResponse response){ response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD"); response.setHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept"); response.setHeader("Access-Control-Max-Age", "1728000"); } private String getResponse(SlingHttpServletRequest request) { String fName = request.getParameter("fname"); String lName = request.getParameter("lname"); String responseText = "Your first name is " + fName + " and your last name is " + lName; return responseText; } }

 

 

If I make an HTTP GET request to any page on my site (they all have resourceType "mysite/components/structure/page") with the selector, credentials in the headers, and a querystring of "?fname=Marvin&lname=Palmer", it returns "Your first name is Marvin and your last name is Palmer" as expected.

 

But if I make an HTTP POST to this servlet with (same page, selector, credentials) and pass the params in the post body, I get a 500 error and "java.lang.IllegalArgumentException" saying value for key 'fname' can't be put into node: Marvin.

 

Interestingly, if I HTTP POST (with credentials) using the same url + "/jcr:content", then I get a 200 response, and lname and fname are written with values "Marvin" and "Palmer" to the JCR at that node path. 

 

But I can't figure out how to get the request to result in execution of my doPost() method. I was able to get this doPost() to work when I registered the servlet using a "bin/biosync" path instead of using resourceType, but I've read that's a discouraged practice. 

 

What am I doing wrong?

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by Manjunath_K

Hi @mpalme1 

Whenever we register servlet using resourceType, then the request url for that servlet will be "${resource.path}.extension" here path value will be path where this component is added in any page. so, try to add this in data-attribute in your component html, inspect the page source of the page where this component is added & check the path. you need access this value in javascript to pass this url as ajax request url.

 

Component html :

<div id="compname-resource-path" data-resource-path="${resource.path}.extension">

 

</div>

 

$('#compname-resource-path').data('resource-path'); //request url

1 reply

Manjunath_K
Manjunath_KAccepted solution
Level 7
October 14, 2020

Hi @mpalme1 

Whenever we register servlet using resourceType, then the request url for that servlet will be "${resource.path}.extension" here path value will be path where this component is added in any page. so, try to add this in data-attribute in your component html, inspect the page source of the page where this component is added & check the path. you need access this value in javascript to pass this url as ajax request url.

 

Component html :

<div id="compname-resource-path" data-resource-path="${resource.path}.extension">

 

</div>

 

$('#compname-resource-path').data('resource-path'); //request url

mpalme1
mpalme1Author
Level 3
October 14, 2020
Except I'm not trying to call the servlet from a component. I actually need to be able to call the servlet from a program running outside of AEM.