POST from 3rd party client to SlingServlet registered using resourceTypes

mpalme1

14-10-2020

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?

servlet sling

Accepted Solutions (1)

Accepted Solutions (1)

Manjunathh

14-10-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

Answers (0)