HTML5 Signature Capture & Storage via App Engine

Romin Irani
Romin Irani’s Blog
7 min readDec 2, 2013

December 2017: Please note that this post has not been updated for a while and there could be differences in terms of commands, screenshots and problems in running the code.

If you have written any Field Service Application that had to do with delivering items to a customer, you would have come across a requirement that needs to capture the signature of the person who received the items.

signature-capture

Image Reference: http://livecourier.wordpress.com/tag/signature-capture/
This blog post demonstrates a working application of how you can use a pure web application to capture the signature and transmit that for storage to a back-end application running on Google App Engine.

Prerequisites

  • Basic understanding of Web development. HTML and Java Script should suffice.
  • Basic understanding of Java Web Development, which includes Servlets, JSP, WAR file structure, etc.
  • You have a working development environment for Google App Engine. This includes the Google Eclipse plugin. The code for persisting the signature uses JDO (Java Data Objects).

What this Episode covers

  • Capture a signature on a Web page using the Java Script Signature Pad developed by Thomas Bradley.
  • Post the signature data to a Java back-end application running on Google App Engine. And of course persist the signature data.
  • Retrieve the signature from the Java Web application and display it on a web page.

Please note that focus is on demonstrating the functionality and not on building out all validations and checks.

My Development Environment

  • Eclipse Juno
  • Google Eclipse plugin with App Engine SDK 1.8.8

You may have another version of Eclipse and older versions of SDK. I believe it will work fine and you need not have the latest version of the App Engine SDK for this to work.

Signature Capture and Display in Action

Let us check out the application in action first. This will help to understand the code much better.

The application is hosted for you at http://hereismysign.appspot.com

Visit the above link. It should bring up a web form as shown below:

sigcap-1

The form is kept simple for now. Simply enter your name and then scribble your signature in the area as shown below:

sigcap-2

Then click on the Submit button. This will submit the button and will show your signature in the list of signatures that have been received so far by the application in the last 30 minutes. When you click submit, what happens is that the signature data captured on the web client is sent as a HTTP POST to the Application running on Google App Engine. It is then persisted in the Data store.

I have deliberately kept a Cron Job running that clears the signatures every 30 minutes, so that my app data store does not get flooded up.

sigcap-3

If you would like to sign again, click on the Sign Again link above.

Sounds good? Let’s get on with the code.

Download Full Source Code

I suggest that you begin with a full download of the project source code.

Go ahead & download the code from : https://github.com/rominirani/SignatureCapture

This is an Eclipse project that you can import directly. For the sake of reducing the code size, I have removed the App Engine SDK Jars from the WEB-INF\lib folder. So depending on the version of your App Engine SDK in the Eclipse development environment on your machine, please link to the appropriate App Engine SDK that you have for the project to build successfully.

If you are successful with importing the project into your Eclipse setup, the project directory should look something like this:

sigcap-4

Entity Mode, DAO and Service Classes

Let us first look at the App Engine Entity side of things. We are going to keep things simple, so we are going to have minimum attributes that we want to capture and persist as the Entity.

If you observed the UI above and accessed the application, we are going to model our SignatureRecord entity which will have only the following attributes:

  • ID : This is the auto generated Key. We will leave that to App Engine.
  • Receiver Name : This is receiver name entered on the form.
  • Signature Data : This is the signature data in bytes that form the image that is your signature. We are going to be using the TEXT type for saving this information.
  • Date Time Stamp : This is the date time stamp that the record was saved.

Our entity class is named SignatureRecord and it is shown below:

To work with the entity class, we are going to write a DAO (SignatureRecordDAO.java) with some utility methods for Adding a Signature Record, Deleting All Signature Records and Retrieving the List of Signature Records. The DAO Class uses Java Data Objects. The code is straight forward to understand as given below:

Finally, we have the Service class (SignatureCaptureService.java). This is the Java Servlet that will expose a HTTP POST method. This POST method will be invoked by the Web form when submitting the signature data.

OK. Now that the back-end service and persistence has been figured out, let us move to the front-end. First up is the signature.jsp page that allows you to capture the name of the person receiving the page and the signature.

The code is shown below:

Let us go through the important points for signature.jsp:

  • I am using the excellent Signature Pad jQuery plugin from Thomas Bradley. If you download the ZIP file from the above link, you will get a bunch of js, css files. I have referenced the required files i.e. CSS (on line 8) and JS (on line 34).
  • The <form> tag starting from line 17 is a standard one. It contains the receiverName text input field (line 19) and the key stuff for signature begins on line 25.
  • The Signature Pad plugin is useful HTML5 canvas which we have used here. Frankly speaking the snippet of HTML code is straight from the samples provided.
  • The main thing to note is that I have created a hidden form variable named signature that will contain the actual signature bytes from the canvas. This form parameter will be populated just prior to submitting it to the server.
  • The submitform code starting on line 39 validates if the receiver name is provided. Then it calls one of the Signature pad methods to get the get the Signature Image. Notice that in the document ready function for jQuery library, we had initialized the Signature Pad element.
  • The value received from the api.getSignatureImage() method is a Data URI scheme for the src attribute of the <img> HTML element. Check the reference.
  • The Form data is submitted via the POST method to the /signatureservice endpoint. This endpoint is nothing but the Servlet that we created above i.e. SignatureCaptureService.java. The servlet mapping will be found in the WEB-INF\web.xml file.

Once the signature is saved, the response will be send to the list.jsp file, that displays a list of signatures that have been captured in the last 30 minutes. The code is shown below:

Let us go through the important points for list.jsp:

  • The JSP file simply contains a code snippet that invokes the getSignatureRecords() method of the SignatureRecordDAO class. It iterates through the records and renders the records in a HTML table.
  • Note that we simply assigned the value of the getSignature() method directly to the src attribute of the img element. This is because the data that is stored in the signature attribute of the SignatureRecord entity in the Data Store is of the correct format i.e. the Data URI scheme. The next section shows that.

App Engine Administration Console

If you access the App Engine Admin Console for your application and navigate to the Data Store, you will notice that the signature attribute for the SignatureRecord entities is being saved as given below.

sigcap-5

Bonus Feature

While not core to the functionality, I have also written a Cron Job that runs every 30 minutes. It clears up all the SignatureRecord entities in the datastore. You will find the code for the same in the com.mindstorm.signaturecapture.cron package. It invokes the deleteAll() method of the SignatureDAO.java class.

Hope you liked this App Engine episode. Till the next time, stay tuned and give me feedback. If you run into issues, do drop a note, I will do my best to get it working for you.

--

--

Romin Irani
Romin Irani’s Blog

My passion is to help developers succeed. ¯\_(ツ)_/¯