Expand my Community achievements bar.

Adaptive Form - 'File Attachment' component leads to 'Encountered an internal error while submitting the form' on submit

Avatar

Level 2

Hi All,

I am getting an error while submitting any attachment from Adaptive form

Error:

rakesh443_0-1660302459741.png

Adaptive Form :

rakesh443_1-1660302580567.png

 

Has anyone has suggestions on this process.

 

Thanks

Rakesh

 

19 Replies

Avatar

Employee Advisor

@rakesh443 

I have seen this issue earlier, so asking a couple of additional questions:

1. Are you seeing this issue with the "Submit to REST endpoint with POST" submission ONLY?

2. Can you replicate the issue with a direct author/publish URL?

 

Please share the error log for this attempt for a quick review. Just a hunch, are you seeing "org.apache.http.ProtocolException: Target host is not specified" in the logs?

 

Avatar

Level 2

Yes I am getting error only I use "Submit to REST endpoint with POST" by checking the check box

 

Error Log:

12.08.2022 18:49:50.150 *ERROR* [[0:0:0:0:0:0:0:1] [1660310389726] POST /content/forms/af/finalform/jcr:content/guideContainer.af.submit.jsp HTTP/1.1] com.adobe.aemds.guide.service.impl.RESTSubmitActionService Failed to make REST call
org.apache.http.client.ClientProtocolException: null
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:187) [org.apache.httpcomponents.httpclient:4.5.12]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) [org.apache.httpcomponents.httpclient:4.5.12]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) [org.apache.httpcomponents.httpclient:4.5.12]

Avatar

Employee Advisor

@rakesh443 

Thanks for confirming! It's the same issue wherein the target host is missing.

1. Can you provide the complete URL in the endpoint - http://host:port/path_to_rest_end_point and 

2. Exclude the path_to_rest_end_point from the authentication requirement under the "Sling authentication service" under http://host:port/system/console/configMgr

 

Hope this helps!

Avatar

Level 2

@Pulkit_Jain_ 

I have excluded the path, but I am getting the following errors

 

rakesh443_0-1660315833365.png

Errors : 

for URL in the endpoint :

localhost:4502/bin/myServlet
org.apache.http.client.ClientProtocolException: URI does not specify a valid host name: localhost:4502/bin/myServlet


for URL in the endpoint :

http://localhost:4502/bin/myServlet
java.lang.IllegalArgumentException: Can't create child on a synthetic root

 

for URL in the endpoint :

/bin/myServlet
org.apache.http.client.ClientProtocolException: null
Caused by: org.apache.http.ProtocolException: Target host is not specified

 

Avatar

Employee Advisor

@rakesh443 

Not sure how you're accessing the form/submitting the form, but can you try IP/FQDN instead of localhost?

I have got a similar form to work inhouse. 

Avatar

Employee Advisor

@rakesh443 where is your rest endpoint hosted? and on what web server?

Avatar

Level 2

endpoint point will be the servlet in the same server where AEM is hosted.

right now I am testing in the my local instance

endpoint : localhost:4502/bin/myServlet

Avatar

Level 2

@workflowuser

we tried, we got Thank you page, but data is submitted to the servlet and not even the log were generated. It was like the servlet was not been called.

 

 

rakesh443_0-1660325188039.png

path of the custom action button:  "apps/CustomSubmit"

____________________________________________________________

post.POST.jsp

 

<%@include file="/libs/foundation/global.jsp"%>
<%@taglib prefix="cq" uri="http://www.day.com/taglibs/cq/1.0"%>
<%@ page import="java.util.*,org.apache.sling.api.request.RequestParameter,com.day.cq.wcm.api.WCMMode,org.apache.sling.api.request.*" %>
<%@ page import="org.apache.http.entity.mime.MultipartEntity" %>
<%@ page import="org.apache.http.entity.ContentType" %>
<%@ page import="org.apache.http.client.methods.HttpPost" %>
<%@page session="false" %><%
%><%


com.adobe.aemds.guide.utils.GuideSubmitUtils.setForwardPath(slingRequest,"/bin/myServlet",null,null);


%>

_______________________________________________________________________

 

Do we need to add anything more?

 

Thanks

Avatar

Employee Advisor

this is the code that works for reading excel file - can you please compare this to your code

package com.embedpdf.core.servlets;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

import javax.servlet.Servlet;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
@component(service={Servlet.class}, property={Constants.SERVICE_DESCRIPTION+"=Servlet to parse excel file","sling.servlet.methods=post", "sling.servlet.paths=/bin/parseExcel"})

public class ReadExcelAttachment extends SlingAllMethodsServlet {
/**
*
*/
private static final long serialVersionUID = 1L;

protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException
{
CSVFormat csvFormat = CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase();

final boolean isMultipart = org.apache.commons.fileupload.servlet.ServletFileUpload.isMultipartContent(request);
if (isMultipart)
{
java.util.Map<String, org.apache.sling.api.request.RequestParameter[]> params = request
.getRequestParameterMap();

for (final java.util.Map.Entry<String, org.apache.sling.api.request.RequestParameter[]> pairs : params
.entrySet())
{
final org.apache.sling.api.request.RequestParameter[] pArr = pairs.getValue();
final org.apache.sling.api.request.RequestParameter param = pArr[0];

try {
if (!param.isFormField()) {
System.out.println("Got attachment");
CSVParser csvParser = CSVParser.parse( param.getInputStream(),StandardCharsets.UTF_8, csvFormat);
for(CSVRecord csvRecord : csvParser) {
String firstName = csvRecord.get("First Name");
String lastName = csvRecord.get("Last Name");
String email = csvRecord.get("Email");
String phoneNumber = csvRecord.get("Phone Number");

System.out.println(firstName + "," + lastName + "," + email + "," + phoneNumber);
}
csvParser.close();

}
}
catch(Exception e)
{
System.out.println("Got Error "+e.getMessage());
}
}
}
}
}

 

Avatar

Level 2

@workflowuser 

Thanks, but actually we are not able to hit the servlet when we submit. we are missing something. Do we need write any javascript in submitButton? 

Avatar

Employee Advisor

lets do a web session

send me a link via private message

Avatar

Level 1

Was this ever figured out? I'm having the exact same problem - happens when I try to submit from an AEM form to an AEM servlet endpoint, and I did all the correct configuration in CSRF and excluded the path in the authentication manager. All my servlet has in it is an empty "doPost" override.

Avatar

Level 5

What I see on your screenshot looks ok to me.

Just some usual questions:

1) What AEM version are you on?

2) What happens when you check your servlet in Adobe Experience Manager Web Console - Sling Servlet Resolver (http://localhost:4502/system/console/servletresolver)

3) Do you get to the Thank You Page with this submit action ?

Avatar

Community Advisor

Add below code in post.POST.jsp file while creating custom submit action.

"/bin/storeafsubmission" this is my servlet path.

This code works for me in aem 6.4 version

 

<%@include file="/libs/fd/af/components/guidesglobal.jsp"%>
<%@include file="/libs/foundation/global.jsp"%>

<%@ page import="org.apache.sling.api.request.RequestParameter,
com.day.cq.wcm.api.WCMMode,
com.day.cq.wcm.foundation.forms.FormsHelper,
org.apache.sling.api.resource.ResourceUtil,
org.apache.sling.api.resource.ValueMap,
com.adobe.forms.common.submitutils.CustomParameterRequest,
com.adobe.aemds.guide.utils.*" %>

<%@ page import="org.apache.sling.api.request.RequestParameter,
com.day.cq.wcm.api.WCMMode" %>

<%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling/1.0"%>
<%@taglib prefix="cq" uri="http://www.day.com/taglibs/cq/1.0"%>

<cq:defineObjects/>
<sling:defineObjects/>
<%@page session="false" %>
<%

com.adobe.aemds.guide.utils.GuideSubmitUtils.setForwardPath(slingRequest,"/bin/storeafsubmission",null,null);

%>

 

Links to create custom submit actions:

https://experienceleague.adobe.com/docs/experience-manager-learn/forms/adaptive-forms/custom-submit-...

Avatar

Community Advisor
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

Community Advisor
AEM_MYSQL_VK  : this should be the datasource name given in OSGI config 

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

 

Avatar

Employee Advisor

go to http://localhost:4502/system/console/bundles

Click on your bundle

scroll down and check if all entries in the Declarative Service Components are active