I have created a POST servlet like below:
package com.aem.sites.servlets;
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;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
@Component(
immediate = true,
service = Servlet.class,
configurationPid = "com.aem.sites.servlets.SubscriptionSevlet",
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 SubscriptionSevlet extends SlingAllMethodsServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
/** The Constant logger. */
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
protected void doPost(final SlingHttpServletRequest req, final SlingHttpServletResponse res) throws IOException, ServletException {
logger.info("======================inside do post for subscription servlet========================================");
}
/**
* Activate.
*
* @param config the config
*/
@Activate
@Modified
protected void Activate(SubscriptionConfiguration config) {
logger.info("********************************inside subscription servlet*****************************************"+config.sampleProperty());
}
}
and this is the configuration Interface
package com.aem.sites.interfaces;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@ObjectClassDefinition(name="Subscription Configuration", description="Configuration interface for Subscription Servlet")
public @interface SubscriptionConfiguration {
@AttributeDefinition(
name = "Sample property",
description = "Sample property",
type = AttributeType.STRING
)
public String sampleProperty() default "sample test";
}
I am calling the servlet using resourceType and selector.The servlet is being called through a form:
<div id="login-box" style="padding-top:5%;padding-left:3%">
<div class="left">
<h1>Sign up</h1>
<form method="POST" name="subscriptionForm" id="subscriptionForm" action="/content/aemsite/en/subscribe.newsletters.html">
<input type="text" name="name" placeholder="Name" style="width:30%" />
<input type="text" name="email" placeholder="E-mail" style="width:30%"/>
<input type="submit" name="signup_submit" value="Sign me up" />
</form>
</div>
</div>
this is the JS being included through clientlibs
$(function() {
var formURL = $("#subscriptionForm").attr('action');
var method = $("#subscriptionForm").attr('method');
$("#subscriptionForm").submit(function(event) {
event.preventDefault();
$.ajax({
url:formURL,
data: $("#subscriptionForm").serialize(),
type: method,
success: function( data, textStatus, jQxhr ){
$('#response pre').html( data );
},
error: function( jqXhr, textStatus, errorThrown ){
console.log( errorThrown );
}
});
});
});
The clientlibs that are being included as dependencies are given in the screenshot clientlibs.png below
The above is the error I am seeing on the chrome debuuger is "Failed to load resource: the server responded with a status of 500 (Server Error)"
The screenshot is given below:
I have 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 have also used jcrresolver to check if the path is being resolved and here is the screenshot attached of that:
The servlet's status is also active.
I am not sure what is it that I am doing incorrectly. Any help is appreciated.
Thanks
Solved! Go to Solution.
I just tested Mail List Component solution. It works nicely --
Data was posted to Servlet and put into the database
Views
Replies
Total Likes
See this i article - it will show you everything you need to do - you can even build the example ToyStore site and learn how to post data to a servlet and then write that data to a database (this is the example use case). But the important thing for you is it will show you posting to a Servlet.
Creating a Mail List Sign Up Component for the Experience Manager Toy Store Site
Views
Replies
Total Likes
look for this request on /system/console/requests and post the output for the failing request here.
Jörg
Views
Replies
Total Likes
I just tested Mail List Component solution. It works nicely --
Data was posted to Servlet and put into the database
Views
Replies
Total Likes
Thank you for the response @Scott. The only thing I am doing differently here is adding cq.jquery as the categories in the project already. I am still getting 500 error.
@jorg Thank you for the response. The response on the /system/console/requests for the POST is
0 TIMER_START{Request Processing}
1 COMMENT timer_end format is {<elapsed microseconds>,<timer name>} <optional message>
7 LOG Method=POST, PathInfo=null
11 TIMER_START{handleSecurity}
23360 TIMER_END{23348,handleSecurity} authenticator org.apache.sling.auth.core.impl.SlingAuthenticator@2154aa1c returns true
23548 TIMER_START{ResourceResolution}
23857 TIMER_END{308,ResourceResolution} URI=/content/aemsite/en/subscribe.newsletters.html resolves to Resource=JcrNodeResource, type=cq:Page, superType=null, path=/content/aemsite/en/subscribe
23862 LOG Resource Path Info: SlingRequestPathInfo: path='/content/aemsite/en/subscribe', selectorString='newsletters', extension='html', suffix='null'
23862 TIMER_START{ServletResolution}
23864 TIMER_START{resolveServlet(/content/aemsite/en/subscribe)}
29912 TIMER_END{6045,resolveServlet(/content/aemsite/en/subscribe)} Using servlet org.apache.sling.servlets.post.impl.SlingPostServlet
29936 TIMER_END{6073,ServletResolution} URI=/content/aemsite/en/subscribe.newsletters.html handled by Servlet=org.apache.sling.servlets.post.impl.SlingPostServlet
29940 LOG Applying Requestfilters
29942 LOG Calling filter: com.adobe.granite.resourceresolverhelper.impl.ResourceResolverHelperImpl
29948 LOG Calling filter: org.apache.sling.i18n.impl.I18NFilter
29950 LOG Calling filter: com.adobe.granite.httpcache.impl.InnerCacheFilter
29967 LOG Calling filter: org.apache.sling.rewriter.impl.RewriterFilter
29969 LOG Calling filter: com.adobe.cq.mcm.campaign.servlets.CampaignCopyTracker
29971 LOG Calling filter: com.adobe.cq.history.impl.HistoryRequestFilter
30444 LOG Calling filter: com.day.cq.wcm.core.impl.WCMRequestFilter
30453 LOG Calling filter: com.adobe.cq.wcm.core.components.internal.servlets.CoreFormHandlingServlet
30455 LOG Calling filter: com.adobe.granite.optout.impl.OptOutFilter
30460 LOG Calling filter: com.day.cq.wcm.foundation.forms.impl.FormsHandlingServlet
30461 LOG Calling filter: com.adobe.cq.social.commons.cors.CORSAuthenticationFilter
30463 LOG Calling filter: org.apache.sling.engine.impl.debug.RequestProgressTrackerLogFilter
30465 LOG Calling filter: com.day.cq.wcm.mobile.core.impl.redirect.RedirectFilter
30466 LOG Calling filter: com.day.cq.wcm.core.impl.AuthoringUIModeServiceImpl
30863 LOG Calling filter: org.apache.sling.security.impl.ContentDispositionFilter
30865 LOG Calling filter: com.adobe.granite.csrf.impl.CSRFFilter
31281 LOG Calling filter: com.adobe.granite.rest.assets.impl.AssetContentDispositionFilter
31284 LOG Calling filter: com.adobe.granite.requests.logging.impl.RequestLoggerImpl
31288 LOG Calling filter: com.adobe.granite.rest.impl.servlet.ApiResourceFilter
31294 LOG Calling filter: com.adobe.cq.social.ugcbase.security.impl.SaferSlingPostServlet
31300 LOG Calling filter: com.day.cq.wcm.core.impl.warp.TimeWarpFilter
31304 LOG Calling filter: com.day.cq.dam.core.impl.servlet.ActivityRecordHandler
31315 LOG Calling filter: com.day.cq.dam.core.impl.assetlinkshare.AdhocAssetShareAuthHandler
31319 LOG Applying Componentfilters
31319 LOG Calling filter: com.day.cq.personalization.impl.TargetComponentFilter
31321 LOG Calling filter: com.day.cq.wcm.core.impl.WCMComponentFilter
31433 LOG Calling filter: com.day.cq.wcm.core.impl.WCMDebugFilter
31460 TIMER_START{org.apache.sling.servlets.post.impl.SlingPostServlet#0}
31527 LOG Calling PostOperation: org.apache.sling.servlets.post.impl.operations.ModifyOperation
35719 LOG Found processor for post processing ProcessorConfiguration: {contentTypes=[text/html], order=-1, active=true, valid=true, processErrorResponse=true, pipeline=(generator=Config(type=htmlparser, config=JcrPropertyMap [node=Node[NodeDelegate{tree=/apps/aemsite-project/config/rewriter/default/generator-htmlparser: { jcr:primaryType = nt:unstructured, includeTags = [A, /A, IMG, AREA, FORM, BASE, LINK, SCRIPT, BODY, /BODY]}}], values={jcr:primaryType=nt:unstructured, includeTags=[Ljava.lang.String;@14f55699}]), transformers=(Config(type=linkchecker, config={}), Config(type=mobile, config=JcrPropertyMap [node=Node[NodeDelegate{tree=/apps/aemsite-project/config/rewriter/default/transformer-mobile: { jcr:primaryType = nt:unstructured, component-optional = true}}], values={jcr:primaryType=nt:unstructured, component-optional=true}]), Config(type=mobiledebug, config=JcrPropertyMap [node=Node[NodeDelegate{tree=/apps/aemsite-project/config/rewriter/default/transformer-mobiledebug: { jcr:primaryType = nt:unstructured, component-optional = true}}], values={jcr:primaryType=nt:unstructured, component-optional=true}]), Config(type=contentsync, config=JcrPropertyMap [node=Node[NodeDelegate{tree=/apps/aemsite-project/config/rewriter/default/transformer-contentsync: { jcr:primaryType = nt:unstructured, component-optional = true}}], values={jcr:primaryType=nt:unstructured, component-optional=true}]), Config(type=versioned-clientlibs, config={}), serializer=Config(type=htmlwriter, config={}))}
39827 TIMER_END{8365,org.apache.sling.servlets.post.impl.SlingPostServlet#0}
39849 LOG Filter timing: filter=com.day.cq.wcm.core.impl.WCMDebugFilter, inner=8, total=8, outer=0
39851 LOG Filter timing: filter=com.day.cq.wcm.core.impl.WCMComponentFilter, inner=8, total=8, outer=0
39883 TIMER_END{39883,Request Processing} Request Processing
40645 LOG Filter timing: filter=com.day.cq.dam.core.impl.assetlinkshare.AdhocAssetShareAuthHandler, inner=8, total=8, outer=0
40647 LOG Filter timing: filter=com.day.cq.dam.core.impl.servlet.ActivityRecordHandler, inner=8, total=8, outer=0
40649 LOG Filter timing: filter=com.adobe.cq.dam.webdav.impl.io.DamWebdavRequestFilter, inner=8, total=8, outer=0
40651 LOG Filter timing: filter=com.day.cq.wcm.core.impl.warp.TimeWarpFilter, inner=8, total=8, outer=0
40653 LOG Filter timing: filter=com.adobe.cq.social.ugcbase.security.impl.SaferSlingPostServlet, inner=8, total=8, outer=0
40654 LOG Filter timing: filter=com.day.cq.dam.core.impl.servlet.DamContentDispositionFilter, inner=8, total=8, outer=0
40656 LOG Filter timing: filter=com.adobe.granite.rest.impl.servlet.ApiResourceFilter, inner=8, total=8, outer=0
40657 LOG Filter timing: filter=com.adobe.granite.requests.logging.impl.RequestLoggerImpl, inner=8, total=8, outer=0
40659 LOG Filter timing: filter=com.adobe.granite.rest.assets.impl.AssetContentDispositionFilter, inner=8, total=8, outer=0
40661 LOG Filter timing: filter=com.adobe.granite.csrf.impl.CSRFFilter, inner=8, total=9, outer=1
40662 LOG Filter timing: filter=org.apache.sling.security.impl.ContentDispositionFilter, inner=9, total=9, outer=0
40664 LOG Filter timing: filter=com.day.cq.wcm.core.impl.AuthoringUIModeServiceImpl, inner=9, total=9, outer=0
40665 LOG Filter timing: filter=com.day.cq.wcm.mobile.core.impl.redirect.RedirectFilter, inner=9, total=9, outer=0
40667 LOG Filter timing: filter=org.apache.sling.engine.impl.debug.RequestProgressTrackerLogFilter, inner=9, total=10, outer=1
40669 LOG Filter timing: filter=com.adobe.cq.social.commons.cors.CORSAuthenticationFilter, inner=10, total=10, outer=0
40670 LOG Filter timing: filter=com.day.cq.wcm.foundation.forms.impl.FormsHandlingServlet, inner=10, total=10, outer=0
40672 LOG Filter timing: filter=com.adobe.granite.optout.impl.OptOutFilter, inner=10, total=10, outer=0
40673 LOG Filter timing: filter=com.adobe.cq.wcm.core.components.internal.servlets.CoreFormHandlingServlet, inner=10, total=10, outer=0
40675 LOG Filter timing: filter=com.day.cq.wcm.core.impl.WCMRequestFilter, inner=10, total=10, outer=0
40677 LOG Filter timing: filter=com.adobe.cq.history.impl.HistoryRequestFilter, inner=10, total=11, outer=1
40678 LOG Filter timing: filter=com.adobe.cq.mcm.campaign.servlets.CampaignCopyTracker, inner=11, total=11, outer=0
40680 LOG Filter timing: filter=org.apache.sling.rewriter.impl.RewriterFilter, inner=11, total=11, outer=0
40682 LOG Filter timing: filter=com.adobe.granite.httpcache.impl.InnerCacheFilter, inner=11, total=11, outer=0
40683 LOG Filter timing: filter=org.apache.sling.i18n.impl.I18NFilter, inner=11, total=11, outer=0
40685 LOG Filter timing: filter=org.apache.sling.distribution.servlet.DistributionAgentCreationFilter, inner=11, total=11, outer=0
Views
Replies
Total Likes
29912 TIMER_END{6045,resolveServlet(/content/aemsite/en/subscribe)} Using servlet org.apache.sling.servlets.post.impl.SlingPostServlet
29936 TIMER_END{6073,ServletResolution} URI=/content/aemsite/en/subscribe.newsletters.html handled by Servlet=org.apache.sling.servlets.post.impl.SlingPostServlet
Your servlet is not invoked at all, but the SlingPostServlet.
Jörg
Views
Replies
Total Likes
Can you try that example i give you (install the finished solition package)- set a small MySQL database with Customer table and follow the doc.
See if that works for you.
I just tested and it works!
Views
Replies
Total Likes
I suspected if there is a problem with the servlet itself or the action path set in the HTML but it all works fine when I use the GET method. It's only when it's a POST request when I am facing this issue.These are the dependencies I have added to the project i, can any of these libraries pose issue ?
cq.jquery
granite.utils
granite.jquery
granite.shared
cq.shared
underscore
Views
Replies
Total Likes
Not sure as i have never had issue of posting to an AEM Servlet - you may have found a bug. But before we go down that path - see if the example i give you works on your system. It uses AJAX to post to a servlet.
Views
Replies
Total Likes
How does your POST request look like? Can you post the exact adress you are posting to?
@Scott: I don't think that there is a bug in Sling; I have used this very functionality already a few times :-)
Jörg
Views
Replies
Total Likes
Makes sense - i have never seen issue here.
Views
Replies
Total Likes
The path used in action is /content/aemsite/en/subscribe.newsletters.html while the page that has the POST form is http://localhost:4502/editor.html/content/aemsite/en/subscribe.html Since this is an AJAX call I have selected the path in action to be /content/aemsite/en/subscribe.newsletters.html while 'newsletters' is the selector. Is there something I am doing wrong here ?
Views
Replies
Total Likes
Update - When I use the path instead of resourceType, it works fine.
Sorry, but hardcoding the path in the servlet is no solution! Don't do that for production code.
My assumption is that the page at /content/aemsite/en/subscribe does not have the resourcetype "aemsite-project/components/structure/page" as specified in the annotations of the servlet. Fix that and it will work!
Jörg
Never meant I found a solution. Was just an observation. The /content/aemsite/en/subscribe is made using an editable template and the resource type is set to aemsite-project/components/structure/page.
Views
Replies
Total Likes
And if the resourceType wasn't correct it would have never worked for GET request either.
Views
Replies
Total Likes
That's true.
Anyway, the SlingPostServlet was used. Maybe you can confirm this by validating your request through the servlet resolver page in the webconsole (localhost:4502/system/console/servletresolver).
Looking again at your code, the annotations seems to be wrong ...
@Component(
immediate = true,
service = Servlet.class,
configurationPid = "com.aem.sites.servlets.SubscriptionSevlet",
property = {
"sling.servlet.methods=POST",
"sling.servlet.selectors=newsletters",
"sling.servlet.resourceTypes=aemsite-project/components/structure/page",
"sling.servlet.extensions=html"
}
)
I would expect something like this
@Compont(immediate=true)
@Service
@Properties({
@Property(name="sling.servlet.methods" value="POST"),
@Property(name="sling.servlet.selectors" value="newsletters"),
@Property(name="sling.servlet.resourceTypes" value="aemsite-project/components/structure/page"),
@Property(name="sling.servlet.extensions" value="html")
})
(or the use of the @SlingServlet annotation).
Can you check that?
Jörg
Views
Replies
Total Likes
I was looking to use OSGi DS annotations that's why I didn't use the @SlingServlet annotation. Do you think I should use the Felix SCR annotations for POSTrequest??
Views
Replies
Total Likes
I haven't played that much with the DS annotations yet, I don't know from the top of my head if the property syntax is correct. When I used the Felix SCR annotations it worked for me very well. You might give it a try.
Jörg
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies
Views
Likes
Replies