3
votes

I have created a POST servlet like below:

package com.aem.sites.servlets;

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.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.aem.sites.interfaces.SubscriptionConfiguration;

@Component(immediate=true,
service=Servlet.class,
configurationPid="com.aem.sites.servlets.SubscriptionServlet",
property = {
        "sling.servlet.methods=POST", 
        "sling.servlet.selectors=newsletters",
        "sling.servlet.resourceTypes=aemsite-project/components/structure/page",
        "sling.servlet.extensions=html" 
}
        )
@Designate(ocd=SubscriptionConfiguration.class)
public class SubscriptionServlet extends SlingAllMethodsServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;


    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    protected void doPost(final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws ServletException, IOException  {
        logger.info("====================================================SubscriptionServlet::::::::::SubscriptionConfiguration=====================================");
    }

    @Activate
    @Modified
    protected void Activate(SubscriptionConfiguration config) {
        logger.info("********************************inside SubscriptionConfiguration servlet*****************************************");
    }

}

I am calling the servlet using resourceType and selector.The servlet is being called through a form:

<div id = "sign-up" style ="padding-top:6%;padding-left:2%">
  <div>
    <h1 style="font-size:2em">Subscribe to Newsletters</h1>
    <form name = "subscriptionForm" method = "POST" action="/content/aemsite/en/subscribe.newsletters.html" id="subscriptionForm">
    <input type="text" name="name" id="name" placeholder="Name" style="margin-bottom:1%;width:30%"/>
    <input type="text" name="email" id="email" placeholder="E-mail" style="margin-bottom:1%;width:30%"/>

    <input type="submit" name="signup_submit" value="Sign me up" style="margin-bottom:3%"/>
    </form>
  </div> 

</div>

this is the javascript file that is being included as clientlibs

$(function() {
    $('#subscriptionForm').submit(function(e) {
        e.preventDefault(); //STOP default action
        var formURL = $(this).attr("action");
        var method = $(this).attr("method");
        var name = $('#name').val();
        var email = $('#email').val();
        var form_data = $(this).serialize(); 
        console.log('inside subscription form '+form_data+' formURL '+formURL);
        $.ajax({
            type:method,
            url:formURL,
            data: form_data, success:function(data){
              }
        });
    });
});

I am using the jQuery provided out of the box with AEM. When I submit the form it throws some errors. These are the errors that I am seeing:

Failed to load resource: the server responded with a status of 500 (Server Error)

The above is the error I am seeing on the chrome debuuger. In the error.log file I am seeing this error:

20.11.2017 22:13:42.802 *ERROR* [0:0:0:0:0:0:0:1 [1511234022796] POST /content/aemsite/en/subscribe.newsletters.html HTTP/1.1] org.apache.sling.servlets.post.impl.operations.ModifyOperation Exception during response processing.
javax.jcr.nodetype.ConstraintViolationException: No matching property definition: name = aemsite

and

POST /content/aemsite/en/subscribe.newsletters.html HTTP/1.1] org.apache.sling.jcr.resource.internal.helper.JcrPropertyMapCacheEntry converToType: Cannot convert value of 2017/11/18 02:28:18 to class java.util.Calendar
java.lang.IllegalArgumentException: Not a date string: 2017/11/18 02:28:18

It looks like the POST request is trying to save a property but in the servlet all I am trying to do is output the logger message set in the doPost method of the servlet. When I change the type of request from POST to GET, the errors disappear and the servlet is getting called.

I had read that from AEM 6 onwards more security measures are being adopted for POST request and hence a CSRF token is being used but it is mostly handled if AEM's version of jQuery is used.

I am not sure what is it that I am doing incorrectly. Any help is appreciated.

Thanks in advance

UPDATE:

Result of jcrresolver mapping

enter image description here

3
Did you check if the URL /content/aemsite/en/subscribe.newsletters.html is resolving to your servlet correctly? You can verify through the resource resolver console /system/console/jcrresolver. Also verify if your servlet is active.rakhi4110
Thank you for the response. I can confirm the servlet is active and I have attached the screenshot of the jcrresolver.user972418

3 Answers

2
votes

When you post to a path that resolves to a cq:Page your servlet with resourceType will not get invoked.

Post to - your_page_path/jcr:content to get your resource based servlet to process this request

Also hardcoding the path is not recommended. What I have done in past for such scenarios is to have a component, in your case you could call it subscription component and the form could be posted like -

 <form action="${resource.path}.yourselector.html" method="post">

And your servlet resourceType be the component.

1
votes

When POSTing the default POST servlet is called, for some reason. That is clearly visible since the ModifyOperation is executed.

I suggest that you use the Recent Requests console page to see how your resource is identified and how the script is resolved.

0
votes

I recently found out that trying to do a POST request using resourceType alongwith OSGi might not actually work. Everything works fine when I called POST using path. I have used OSGi DS and for a GET call using resourceType and it works well but changing it to POST doesn't really work. I don't know if that's a bug but this is what I can conclude for now. Using path is the way to do a POST call.