How to Build Web Scanning Application with Gradle

Gradle is an excellent cross-platform project building tool, which supports multiple programming languages, application frameworks, and development tools. In this tutorial, I’d like to share how to build a DWT (Dynamic Web TWAIN) sample project with Gradle.

 dwt_servlet_upload

Web Scanning Application

Create a simple Web scanning application with three buttons for loading images, scanning images and uploading images, respectively.

Steps:

  1. Start a new Web project.
  2. Copy the Dynamsoft’s Resources folder to your project.DWT resources
  3. Create and open Web page index.html.
  4. Include DWT JS files.
    <script type="text/javascript" src="Resources/dynamsoft.webtwain.initiate.js"> </script>
    <script type="text/javascript" src="Resources/dynamsoft.webtwain.config.js"> </script>
  5. Add DWT container.
    <div id="dwtcontrolContainer"></div>
  6. Initialize DWT object.
                Dynamsoft.WebTwainEnv.RegisterEvent('OnWebTwainReady', Dynamsoft_OnReady);
                var DWObject;
    
                function Dynamsoft_OnReady() {
                    DWObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer');    // Get the Dynamic Web TWAIN object that is embeded in the div with id 'dwtcontrolContainer'
                    DWObject.Width = 480;       // Set the width of the Dynamic Web TWAIN Object
                    DWObject.Height = 640;      // Set the height of the Dynamic Web TWAIN Object
                }
  7. Add a button for loading images.
    <input type="button" value="Load Image" onclick="btnLoad_onclick();" />
    
    function btnLoad_onclick() {
                    var OnSuccess = function() {
                    };
    
                    var OnFailure = function(errorCode, errorString) {
                    };
    
                    DWObject.IfShowFileDialog = true;
                    DWObject.LoadImageEx("", EnumDWT_ImageType.IT_ALL, OnSuccess, OnFailure);
    }
  8. Add a button for scanning images.
    <input type="button" value="Scan Image" onclick="AcquireImage();" />
    
    function AcquireImage() {
                    if (DWObject) {
                        DWObject.IfShowUI = false;
                        DWObject.IfDisableSourceAfterAcquire = true;	// Scanner source will be disabled/closed automatically after the scan.
                        DWObject.SelectSource();                        // Select a Data Source (a device like scanner) from the Data Source Manager.
                        DWObject.OpenSource();                          // Open the source. You can set resolution, pixel type, etc. after this method. Please refer to the sample 'Scan' -> 'Custom Scan' for more info.
                        DWObject.AcquireImage();                        // Acquire image(s) from the Data Source. Please NOTE this is a asynchronous method. In other words, it doesn't wait for the Data Source to come back.
                    }
     }
  9. Add a button for uploading images.
    <input id="btnUpload" type="button" value="Upload Image" onclick="btnUpload_onclick()">
    
    function btnUpload_onclick() {
                    DWObject.HTTPPort = 8080;
                    var CurrentPathName = unescape(location.pathname); // get current PathName in plain ASCII
                    var CurrentPath = CurrentPathName.substring(0, CurrentPathName.lastIndexOf("/") + 1);
                    var strActionPage = CurrentPath + "DWTUpload";
                    var strHostIP = "localhost"; // server IP e.g. 192.168.8.84
    
                    var OnSuccess = function(httpResponse) {
                        alert("Succesfully uploaded");
                    };
    
                    var OnFailure = function(errorCode, errorString, httpResponse) {
                        alert(httpResponse);
                    };
    
                    var date = new Date();
                    DWObject.HTTPUploadThroughPostEx(
                            strHostIP,
                            DWObject.CurrentImageIndexInBuffer,
                            strActionPage,
                            date.getTime() + ".jpg",
                            1, // JPEG
                            OnSuccess, OnFailure
                            );
    }

Run the Web page. You can now easily load and scan images to DWT container.

Uploading Images with Servlet

To handle uploaded files with Servlet, you can read the Oracle’s tutorial The fileupload Example Application. Note, your code has to include the following lines:

@WebServlet(name = "FileUploadServlet", urlPatterns = {"/upload"})
@MultipartConfig

Otherwise, getPart() will return null;

Here is the Servlet code:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.dynamsoft.upload;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

@WebServlet(name = "DWTUpload", urlPatterns = {"/DWTUpload"})
@MultipartConfig
public class DWTUpload extends HttpServlet {
    private final static Logger LOGGER =
            Logger.getLogger(DWTUpload.class.getCanonicalName());
    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request,
        HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");

    // Create path components to save the file
    final Part filePart = request.getPart("RemoteFile");
    final String fileName = getFileName(filePart);

    OutputStream out = null;
    InputStream filecontent = null;
    final PrintWriter writer = response.getWriter();

    String realPath = getServletContext().getRealPath("/");
    if (realPath == null)
        realPath = "f:\\web_upload"; // modify the default uploading dir accordingly

    String uploadPath = realPath + File.separator + "upload";

    File uploadDir = new File(uploadPath);
    if (!uploadDir.exists())
        uploadDir.mkdir();

    try {
        out = new FileOutputStream(new File(uploadPath + File.separator
                + fileName));
        filecontent = filePart.getInputStream();

        int read = 0;
        final byte[] bytes = new byte[1024];

        while ((read = filecontent.read(bytes)) != -1) {
            out.write(bytes, 0, read);
        }
        writer.println("New file " + fileName + " created at " + uploadPath);
        LOGGER.log(Level.INFO, "File{0}being uploaded to {1}",
                new Object[]{fileName, uploadPath});
    } catch (FileNotFoundException fne) {
        writer.println("You either did not specify a file to upload or are "
                + "trying to upload a file to a protected or nonexistent "
                + "location.");
        writer.println("<br/> ERROR: " + fne.getMessage());

        LOGGER.log(Level.SEVERE, "Problems during file upload. Error: {0}",
                new Object[]{fne.getMessage()});
    } finally {
        if (out != null) {
            out.close();
        }
        if (filecontent != null) {
            filecontent.close();
        }
        if (writer != null) {
            writer.close();
        }
    }
}

private String getFileName(final Part part) {
    final String partHeader = part.getHeader("content-disposition");
    LOGGER.log(Level.INFO, "Part Header = {0}", partHeader);
    for (String content : part.getHeader("content-disposition").split(";")) {
        if (content.trim().startsWith("filename")) {
            return content.substring(
                    content.indexOf('=') + 1).trim().replace("\"", "");
        }
    }
    return null;
}

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}

Build Web Project with Gradle

To automatically build a Web project with Gradle, we can read Gradle’s tutorial Web Application Quickstart, which introduces how to build a WAR file and run the Web application with Jetty plugin. However, it’s not suitable for our case, because the Jetty plugin does not support Servlet 3.0 API. See the discussion Unable to use servlet 3.0 api in jetty plugin. Fortunately, we can use Gradle Tomcat plugin instead.

Create a Gradle project with the command line:

gradle init

Edit settings.gradle:

include 'web'
rootProject.name = 'dwt_gradle'

Edit build.gradle:

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.bmuschko:gradle-tomcat-plugin:2.1'
    }
}

subprojects {
   apply plugin : "java"
   repositories {
      mavenCentral()
   }
}

Create a subproject web. Here is the folder structure:

web
    /src
        /main
            /java
                /com
                    /dynamsoft
                        /upload
                            /DWTUpload.java 
            /webapp
                /index.html
                /Resources
                /WEB-INF

Create a file build.gradle in your subproject, and add WAR and Tomcat plugins:

apply plugin: "war"
apply plugin: 'com.bmuschko.tomcat'

dependencies {
   providedCompile "javax:javaee-api:6.0"

   def tomcatVersion = '7.0.59'
   tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
    "org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}",
      "org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}"
}

tomcat {
    httpPort = 8080
    httpsPort = 8091
    enableSSL = true
}

Open your command line tool, and type in the following commands:

gradle build
gradle tomcatRunWar

gradle_tomcat_plugin

Now you can have fun with the Web scanning application in your Web browsers.

Source Code

https://github.com/dynamsoft-dwt/Scan-Documents-Gradle