These forums are now Read Only. If you have an Acrobat question, ask questions and get help from one of our experts.

submitForm() and server response to HTTP Post

tkilshaw
Registered: Oct 1 2009
Posts: 5
Answered

I have an AcroForm in a PDF file made with Acrobat 7.

It has a Send button that calls a simple JavaScript that does a submitForm() and sends form field data in FDF format to a Java Tomcat server. My Java servlet gets the posted data and saves it in a database.

So far, so good! But what should the servlet's response to the HTTP post operation be?

If I send nothing back, the browser window shows a blank page.

If I send a web page back, the webpage is displayed and the user needs to hit the browser's back button to return to the PDF file.

If I send the FDF back as the response, the original PDF file remains visible but the FDF file is simply saved as a download with its name given as the servlet name.

What I want is for the original PDF to continue to be visible and when the submitForm() call completes to display a dialog saying that the save succeeded or else giving an error message.

There is a total black hole when it comes to finding out the options for this kind of situation.

Can ayone help?

thanks,

Terry

My Product Information:
Acrobat Pro 7.0.9, Windows
nixopax
Registered: Feb 6 2009
Posts: 105
Hi tkilshaw,

When you submit to your server, you need to ensure that your URL has a #FDF at the end of it so the browser knows to receive a response in FDF format, otherwise the native action is to go to that page. In Acrobat, or the desktop Reader version, FDF is the only response they will receive readily. If an HTML response is received, Acrobat will convert that into a new PDF, and reader will just fail entirely telling you it doesn't know how to deal with text/html. Any other response to Acrobat and the Desktop reader will say it's an unknown response type.

To address this:

Java:response.setContentType("application/vnd.fdf"); PHP:header('Content-type: application/vnd.fdf');

This is the header output that tells the browser/server to send a response as an FDF. I don't use Java for my server side language of choice, but rather PHP, so this answer is based on my experience with how PHP sends an FDF back into the PDF. How you generate the FDF is up to you, whether you have it in a predefined format, or generate it on the fly using the FDF-toolkit Adobe provides. [url=http://www.adobe.com/devnet/acrobat/fdftoolkit.php]This is the FDF-toolkit released by Adobe for Java[/url]

To better understand the FDF, and how to send various responses back, I'd suggest reading the [url=http://partners.adobe.com/public/developer/en/pdf/PDFReference16.pdf]PDF Reference 1.6 (PDF v7)[/url].
AravindK
Registered: Oct 2 2009
Posts: 2
Hi Terry,

To address this issue, first you need to set response content type as response.setContentType("application/vnd.fdf");

Create a FDF file like below and stream this content to client. Basically you can add document level java script code here and when this document is loaded on client side, it executes what ever script we mentioned in After section.

%FDF-1.2
1 0 obj
<<
/FDF
<<
/JavaScript << /After (app.alert("Data Imported Successfully");) >>
>>
>>
endobj
trailer
<<
/Root 1 0 R
>>
%%EOF

Here is the servlet code to send response to client.
response.setContentLength(b.length);
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.getOutputStream().write(b);
response.getOutputStream().flush();
response.getOutputStream().close();

Here b is the byte array of the FDF file which I mentioned on top.

If you still have problem to display confirmation/error message in javascript window, please let me know. I will send sample code. This solution was working for me.

Aravind
tkilshaw
Registered: Oct 1 2009
Posts: 5
I tried to email this to you and then realized I should but my questions here to.

First, thanks for your help.

I would like to see some Java source code if you have some.

I have some questions.

1) why is a byte array used rather than a string for the FDF content?

2) If I change the message sent back in the FDF do I need to change anything elese in it?

3) You say to use:

response.setContentLength(b.length);
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.getOutputStream().write(b);
response.getOutputStream().flush();
response.getOutputStream().close();

For plain HTML I usually use:

oRes.setContentType( "text/html" );
PrintWriter oOut = oRes.getWriter();
oOut.print( sReturn );

Is all that other stuff there to handle the byte array, apart from the setHeader calls?

Many thanks,

Terry
tkilshaw
Registered: Oct 1 2009
Posts: 5
My thanks again to AravindK. His solution worked. Here is my version of it.

I have removed the header set values which I did no understand:

response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");

and am using a String where he used a byte array. Mine still works and is simpler, but I may have thrown away something important, so if anyone reading this knows more, please let us know.

Shown below is my Java servlet. It is called in response to a click on a button in a PDF on a web page. That causes a submitDoc() Javascript step to be executed, which sends FDF content to my HTTP server. This invokes QFormsServlet whose code is shown below.

This servlet does something with the FDF data that is sent to it, then returns some new FDF data that includes JavaScript code that is executed back in the original PDF. This causes an alert window to appear in the PDF form with the message and icon specified in the servlet.

You could change the call to app.alert() in getReturnFDF() if you need it to do something other than just show an alert window.

I am making sure that no newline characters are sent as part of the app.alert() argument string, but there may be other illegal characters that might be sent, as I'm allowing the message part of any exception that occurs to be sent too.

Anyone know what is illegal in FDF content?

package SnappMX.site.app1.com;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class QFormsServlet extends HttpServlet
{
// pass all Gets to POST code

public void doGet( HttpServletRequest oReq, HttpServletResponse oRes )
throws ServletException,
IOException
{
doPost( oReq, oRes );
}public void doPost( HttpServletRequest oReq, HttpServletResponse oRes )
throws ServletException,
IOException
{
String sTitle = "QForms Status";
String sMessage = "";
String sIcon = "3";

try
{
// parse the input

sMessage = parseInput( oReq );
}
catch( Exception e )
{
// JavaScript won't accept multiple lines of text

sMessage = "Error saving the PDF form: " + e.getMessage().replace( "\n", "* " );
sIcon = "0";
}// write the output

oRes.setContentType("application/vnd.fdf");
PrintWriter oOut = oRes.getWriter();
String sFDF = getReturnFDF( sTitle, sMessage, sIcon );
oOut.print( sFDF );
}private String parseInput( HttpServletRequest oReq ) throws Exception
{
String sFormID = oReq.getParameter( "FormID" );
String sReturn = "Form data was saved to the QForms database.";

// here the real code saves the FDF to a SQL database

return sReturn;
}/**
* Compose FDF for return to client PDF.
* @param sTitle
* a string for the alert dialog window's title
* @param sMessage
* a string with the message to be shown in the PDF file
* must not contain line end characters. And there may be other
* forbidden characters that I don't know about yet.
* @param sIcon
* A string containing an integer value which
* determines which icon is displayed in the alert window:
* 0 = Error
* 1 = Warning
* 2 = Question
* 3 = Status
* @return
*/
private String getReturnFDF( String sTitle, String sMessage, String sIcon )
{
StringBuilder sbFDF = new StringBuilder( 200 );
sbFDF.append( "%FDF-1.2\n" );
sbFDF.append( "1 0 obj\n" );
sbFDF.append( "<<\n" );
sbFDF.append( "/FDF\n" );
sbFDF.append( "<<\n" );
sbFDF.append( "/JavaScript << /After (app.alert({ cTitle: '" );
sbFDF.append( sTitle );
sbFDF.append( "', cMsg: '" );
sbFDF.append( sMessage );
sbFDF.append( "', nIcon: " );
sbFDF.append( sIcon );
sbFDF.append( "});) >>\n" );
sbFDF.append( ">>\n" );
sbFDF.append( ">>\n" );
sbFDF.append( "endobj\n" );
sbFDF.append( "trailer\n" );
sbFDF.append( "<<\n" );
sbFDF.append( "/Root 1 0 R\n" );
sbFDF.append( ">>\n" );
sbFDF.append( "%%EOF" );

return sbFDF.toString();
}
}