Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session
SOLVED

Servlet POST Method not supported

Avatar

Level 7

I have several Servlets successfully deployed but, they are all using GET

I have added a servlet for POST.  Below is a snippet of relevant code.

I have removed POST from "Apache Granite CSRF" and "Apache Sling Referrer Filter" - and enabled Empty.

I am getting this error:

405 Method POST not supported
Method POST not supported
Cannot serve request to /bin/StreamPDF in com.s360g.aem.workflowcomponent.core.servlets.StreamPDF
    <pre>
      0 TIMER_START{Request Processing}
      3 COMMENT timer_end format is {&lt;elapsed microseconds&gt;,&lt;timer name&gt;} &lt;optional message&gt;
     10 LOG Method=POST, PathInfo=null
     14 TIMER_START{handleSecurity}
   7709 TIMER_END{7694,handleSecurity} authenticator org.apache.sling.auth.core.impl.SlingAuthenticator@189b106c returns true
   8090 TIMER_START{ResourceResolution}
   8158 TIMER_END{67,ResourceResolution} URI=/bin/StreamPDF resolves to Resource=ServletResource, servlet=com.s360g.aem.workflowcomponent.core.servlets.StreamPDF, path=/bin/StreamPDF
   8166 LOG Resource Path Info: SlingRequestPathInfo: path=&apos;/bin/StreamPDF&apos;, selectorString=&apos;null&apos;, extension=&apos;null&apos;, suffix=&apos;null&apos;
   8166 TIMER_START{ServletResolution}
   8170 TIMER_START{resolveServlet(/bin/StreamPDF)}
   8195 TIMER_END{24,resolveServlet(/bin/StreamPDF)} Using servlet com.s360g.aem.workflowcomponent.core.servlets.StreamPDF
   8198 TIMER_END{31,ServletResolution} URI=/bin/StreamPDF handled by Servlet=com.s360g.aem.workflowcomponent.core.servlets.StreamPDF
   8205 LOG Applying Requestfilters
   8214 LOG Calling filter: com.adobe.granite.resourceresolverhelper.impl.ResourceResolverHelperImpl
   8222 LOG Calling filter: org.apache.sling.security.impl.ContentDispositionFilter
   8226 LOG Calling filter: com.adobe.granite.csrf.impl.CSRFFilter
   8232 LOG Calling filter: org.apache.sling.i18n.impl.I18NFilter
   8237 LOG Calling filter: com.adobe.granite.httpcache.impl.InnerCacheFilter
   8245 LOG Calling filter: org.apache.sling.rewriter.impl.RewriterFilter
   8249 LOG Calling filter: com.adobe.cq.history.impl.HistoryRequestFilter
   8441 LOG Calling filter: com.day.cq.wcm.core.impl.WCMRequestFilter
   8463 LOG Calling filter: com.adobe.fd.core.security.internal.CurrentUserServiceImpl
   8732 LOG Calling filter: com.adobe.cq.wcm.core.components.internal.servlets.CoreFormHandlingServlet
   8764 LOG Calling filter: com.adobe.granite.optout.impl.OptOutFilter
   8773 LOG Calling filter: com.day.cq.wcm.foundation.forms.impl.FormsHandlingServlet
   8776 LOG Calling filter: com.adobe.cq.social.commons.cors.CORSAuthenticationFilter
   8780 LOG Calling filter: com.adobe.livecycle.dsc.clientsdk.internal.ResourceResolverHolderFilter
   8784 LOG Calling filter: org.apache.sling.engine.impl.debug.RequestProgressTrackerLogFilter
   8788 LOG Calling filter: com.adobe.livecycle.content.appcontext.impl.AppContextFilter
   8793 LOG Calling filter: com.aemforms.prefill.core.filters.LoggingFilter
   8797 LOG Calling filter: com.s360g.aem.workflowcomponent.core.filters.LoggingFilter
   8872 LOG Calling filter: com.s360g.aem.cnp.core.filters.LoggingFilter
   8876 LOG Calling filter: com.day.cq.wcm.mobile.core.impl.redirect.RedirectFilter
   8879 LOG Calling filter: com.day.cq.wcm.core.impl.AuthoringUIModeServiceImpl
   8996 LOG Calling filter: com.adobe.granite.rest.assets.impl.AssetContentDispositionFilter
   9000 LOG Calling filter: com.adobe.granite.requests.logging.impl.RequestLoggerImpl
   9005 LOG Calling filter: com.adobe.granite.rest.impl.servlet.ApiResourceFilter
   9041 LOG Calling filter: com.day.cq.dam.core.impl.servlet.ActivityRecordHandler
   9057 LOG Calling filter: com.day.cq.dam.core.impl.assetlinkshare.AdhocAssetShareAuthHandler
   9061 LOG Calling filter: com.adobe.cq.social.ugcbase.security.impl.SaferSlingPostServlet
   9102 LOG Calling filter: com.day.cq.wcm.core.impl.warp.TimeWarpFilter
   9113 LOG Applying Componentfilters
   9115 LOG Calling filter: com.day.cq.personalization.impl.TargetComponentFilter
   9118 LOG Calling filter: com.day.cq.wcm.core.impl.page.PageLockFilter
   9147 LOG Calling filter: com.day.cq.wcm.core.impl.WCMComponentFilter
   9379 LOG Calling filter: com.day.cq.wcm.core.impl.WCMDebugFilter
   9407 TIMER_START{com.s360g.aem.workflowcomponent.core.servlets.StreamPDF#0}
  10122 LOG Applying Error filters
  10129 LOG Calling filter: org.apache.sling.i18n.impl.I18NFilter
  10133 LOG Calling filter: org.apache.sling.rewriter.impl.RewriterFilter
  10177 TIMER_START{handleError:status=405}
  11245 TIMER_END{1066,handleError:status=405} Using handler /libs/sling/servlet/errorhandler/default.jsp
  34511 LOG Found processor for post processing ProcessorConfiguration: {contentTypes=[text/html], order=-1, active=true, valid=true, processErrorResponse=true, pipeline=(generator=Config(type=htmlparser, config={}), transformers=(Config(type=linkchecker, config={}), Config(type=mobile, config=JcrPropertyMap [node=Node[NodeDelegate{tree=/libs/cq/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=/libs/cq/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=/libs/cq/config/rewriter/default/transformer-contentsync: { jcr:primaryType = nt:unstructured, component-optional = true}}], values={jcr:primaryType=nt:unstructured, component-optional=true}]), serializer=Config(type=htmlwriter, config={}))}
  35169 TIMER_END{35167,Request Processing} Dumping SlingRequestProgressTracker Entries
</pre>
 
--- Code ---
...

@component(service = Servlet.class, property = {
Constants.SERVICE_DESCRIPTION + "=Servlet to return PDF",
"sling.servlet.methods=" + HttpConstants.METHOD_POST,
"sling.servlet.paths=" + "/bin/StreamPDF" })
@ServiceDescription("PDF Servlet")
public class StreamPDF extends SlingSafeMethodsServlet {

...
private static final Logger log = LoggerFactory.getLogger(StreamPDF.class);

protected void doPost(final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws ServletException, IOException {
....

}

 

Any ideas?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

I have created this post servlet few days back and it worked for me, refer this if it may help you.




package
com.aem.vk.core.servlets;

import org.apache.commons.io.IOUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.json.JSONException;
import org.json.JSONObject;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.ValueFormatException;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;


@Component(service = Servlet.class, property = { "sling.servlet.methods=get", "sling.servlet.methods=post",
"sling.servlet.paths=/bin/storeafsubmission" })
public class HandleAdaptiveFormSubmission extends SlingAllMethodsServlet {

//private static final Logger log = LoggerFactory.getLogger(HandleAdaptiveFormSubmission.class);
private static final long serialVersionUID = 1L;

@Reference(target = "(&(objectclass=javax.sql.DataSource)(datasource.name=AEM_MYSQL_DB))")
private DataSource dataSource;

protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException {
JSONObject afSubmittedData;
try {
afSubmittedData = new JSONObject(request.getParameter("jcr:data"));
// we will only store the data bound to schema
JSONObject dataToStore = afSubmittedData.getJSONObject("afData").getJSONObject("afBoundData")
.getJSONObject("data");
String formName = afSubmittedData.getJSONObject("afData").getJSONObject("afSubmissionInfo")
.getString("afPath");
//log.debug("The form name is " + formName);
insertData(dataToStore, formName);

} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

public void insertData(org.json.JSONObject jsonData, String formName) throws ClassNotFoundException, SQLException {
//log.debug("The json object I got to insert was " + jsonData.toString());
String insertTableSQL = "INSERT INTO db_vk.formsubmissions(formdata,formname) VALUES(?,?)";
//log.debug("The query is " + insertTableSQL);
Connection c = getConnection();
//Connection c = getConn();
PreparedStatement pstmt = null;
try {
pstmt = null;
pstmt = c.prepareStatement(insertTableSQL);
pstmt.setString(1, jsonData.toString());
pstmt.setString(2, formName);
//log.debug("Executing the insert statment " + pstmt.executeUpdate());
pstmt.executeUpdate();
c.commit();
} catch (SQLException e) {

//log.error("Getting errors", e);
} finally {
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (c != null) {
try {
c.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

public Connection getConnection() {
//log.debug("Getting Connection ");
Connection con = null;
try {

con = dataSource.getConnection();
// log.debug("got connection");
return con;
} catch (Exception e) {
// log.error("not able to get connection ", e);
}
return null;
}

public String getJSONSchema(String afPath) {
// TODO Auto-generated method stub
afPath = afPath.replaceAll("/content/dam/formsanddocuments/", "/content/forms/af/");
Resource afResource = getResolver.getServiceResolver().getResource(afPath + "/jcr:content/guideContainer");
Node resNode = afResource.adaptTo(Node.class);
String schemaNode = null;
try {
schemaNode = resNode.getProperty("schemaRef").getString();
} catch (ValueFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PathNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (schemaNode.startsWith("/content/dam")) {
//log.debug("The schema is in the dam");
afResource = getResolver.getServiceResolver()
.getResource(schemaNode + "/jcr:content/renditions/original/jcr:content");
resNode = afResource.adaptTo(Node.class);
InputStream jsonSchemaStream = null;
try {
jsonSchemaStream = resNode.getProperty("jcr:data").getBinary().getStream();
Charset charset = StandardCharsets.UTF_8;
String jasonSchemaString = IOUtils.toString(jsonSchemaStream, charset);
//log.debug("The Schema is " + jasonSchemaString);
return jasonSchemaString;
} catch (ValueFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PathNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (schemaNode.startsWith("/assets")) {
afResource = getResolver.getServiceResolver()
.getResource(afPath + "/jcr:content/guideContainer/" + schemaNode + "/jcr:content");
resNode = afResource.adaptTo(Node.class);
InputStream jsonSchemaStream = null;
try {
jsonSchemaStream = resNode.getProperty("jcr:data").getBinary().getStream();
Charset charset = StandardCharsets.UTF_8;
String jasonSchemaString = IOUtils.toString(jsonSchemaStream, charset);
//log.debug("The Schema is " + jasonSchemaString);
return jasonSchemaString;
} catch (ValueFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PathNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}

}

View solution in original post

8 Replies

Avatar

Correct answer by
Community Advisor

I have created this post servlet few days back and it worked for me, refer this if it may help you.




package
com.aem.vk.core.servlets;

import org.apache.commons.io.IOUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.json.JSONException;
import org.json.JSONObject;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.ValueFormatException;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;


@Component(service = Servlet.class, property = { "sling.servlet.methods=get", "sling.servlet.methods=post",
"sling.servlet.paths=/bin/storeafsubmission" })
public class HandleAdaptiveFormSubmission extends SlingAllMethodsServlet {

//private static final Logger log = LoggerFactory.getLogger(HandleAdaptiveFormSubmission.class);
private static final long serialVersionUID = 1L;

@Reference(target = "(&(objectclass=javax.sql.DataSource)(datasource.name=AEM_MYSQL_DB))")
private DataSource dataSource;

protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException {
JSONObject afSubmittedData;
try {
afSubmittedData = new JSONObject(request.getParameter("jcr:data"));
// we will only store the data bound to schema
JSONObject dataToStore = afSubmittedData.getJSONObject("afData").getJSONObject("afBoundData")
.getJSONObject("data");
String formName = afSubmittedData.getJSONObject("afData").getJSONObject("afSubmissionInfo")
.getString("afPath");
//log.debug("The form name is " + formName);
insertData(dataToStore, formName);

} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

public void insertData(org.json.JSONObject jsonData, String formName) throws ClassNotFoundException, SQLException {
//log.debug("The json object I got to insert was " + jsonData.toString());
String insertTableSQL = "INSERT INTO db_vk.formsubmissions(formdata,formname) VALUES(?,?)";
//log.debug("The query is " + insertTableSQL);
Connection c = getConnection();
//Connection c = getConn();
PreparedStatement pstmt = null;
try {
pstmt = null;
pstmt = c.prepareStatement(insertTableSQL);
pstmt.setString(1, jsonData.toString());
pstmt.setString(2, formName);
//log.debug("Executing the insert statment " + pstmt.executeUpdate());
pstmt.executeUpdate();
c.commit();
} catch (SQLException e) {

//log.error("Getting errors", e);
} finally {
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (c != null) {
try {
c.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

public Connection getConnection() {
//log.debug("Getting Connection ");
Connection con = null;
try {

con = dataSource.getConnection();
// log.debug("got connection");
return con;
} catch (Exception e) {
// log.error("not able to get connection ", e);
}
return null;
}

public String getJSONSchema(String afPath) {
// TODO Auto-generated method stub
afPath = afPath.replaceAll("/content/dam/formsanddocuments/", "/content/forms/af/");
Resource afResource = getResolver.getServiceResolver().getResource(afPath + "/jcr:content/guideContainer");
Node resNode = afResource.adaptTo(Node.class);
String schemaNode = null;
try {
schemaNode = resNode.getProperty("schemaRef").getString();
} catch (ValueFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PathNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (schemaNode.startsWith("/content/dam")) {
//log.debug("The schema is in the dam");
afResource = getResolver.getServiceResolver()
.getResource(schemaNode + "/jcr:content/renditions/original/jcr:content");
resNode = afResource.adaptTo(Node.class);
InputStream jsonSchemaStream = null;
try {
jsonSchemaStream = resNode.getProperty("jcr:data").getBinary().getStream();
Charset charset = StandardCharsets.UTF_8;
String jasonSchemaString = IOUtils.toString(jsonSchemaStream, charset);
//log.debug("The Schema is " + jasonSchemaString);
return jasonSchemaString;
} catch (ValueFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PathNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (schemaNode.startsWith("/assets")) {
afResource = getResolver.getServiceResolver()
.getResource(afPath + "/jcr:content/guideContainer/" + schemaNode + "/jcr:content");
resNode = afResource.adaptTo(Node.class);
InputStream jsonSchemaStream = null;
try {
jsonSchemaStream = resNode.getProperty("jcr:data").getBinary().getStream();
Charset charset = StandardCharsets.UTF_8;
String jasonSchemaString = IOUtils.toString(jsonSchemaStream, charset);
//log.debug("The Schema is " + jasonSchemaString);
return jasonSchemaString;
} catch (ValueFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PathNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}

}

Avatar

Employee Advisor

@crich2784 

The msg is pointing to the CSRF filter, so a couple of quick checks:

Under /configMgr >> Adobe Granite CSRF Filter 

- Did you add Add the servlet (/bin/StreamPDF) to the Excluded Paths ("filter.excluded.paths") to whitelist your servlet path?

- Enable the POST method

 

Avatar

Employee Advisor

@crich2784 

I think we may need to deep dive into the server-side logs once. Also, are you hitting the servlet via publish or dispatcher URL?

For a quicker turnaround, could you please raise a support ticket to discuss this issue over a screenshare?

Avatar

Employee Advisor

Make sure you are extending sling all methods servlet

Avatar

Level 7

The solution to my problem was easy.  

I was using SlingSafeMethodsServlet instead of SlingAllMethodsServlet

 

* SlingSafeMethodsServlet - If we want to use only the read-only methods then we use this. This base class is actually just a better implementation of the Servlet API HttpServlet class which accounts for extensibility. So extensions of this class have great control over what methods to overwrite. It supports GET, HEAD, OPTIONS etc methods.

 

* SlingAllMethodsServlet - If we want to use methods that write as well, then we use this. This class extends the SlingSafeMethodsServlet by support for the POST, PUT and DELETE methods.