How to Set up a Simple Barcode Reading Server in Java

Java is one of the most popular programming languages in use, especially for client–server web applications. In this article, we are going to talk about how to set up a simple barcode reading server in Java with Jetty as the web server and servlet container.

New Project

Use an IDE like eclipse or a project manager like maven to start a new simple maven project.

Add Dependencies

Modify pom.xml to add dependencies.

  1. Add Dynamsoft Barcode Reader:

    <repositories>
        <repository>
            <id>dbr </id>
            <url>
            https://download2.dynamsoft.com/maven/dbr/jar
            </url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>com.dynamsoft</groupId>
            <artifactId>dbr</artifactId>
            <version>9.6.20</version>
        </dependency>
    </dependencies>
    
  2. Add Jetty to make the app work as a server:

    <dependency>
         <groupId>org.eclipse.jetty</groupId>
         <artifactId>jetty-servlet</artifactId>
         <version>11.0.15</version>
     </dependency>
    <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-server</artifactId>
      <version>11.0.15</version>
    </dependency>
    
  3. Add Gson to parse and generate JSON:

    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.10.1</version>
    </dependency>
    

Write a CLI Tool to Test Reading Barcodes from Images

Let’s first explore how to use the Java edition of Dynamsoft Barcode Reader by writing a CLI tool to read barcodes from a local image.

  1. Create a new class named App which contains public static void main(String[] args).
  2. Import the package of Dynamsoft Barcode Reader.

    import com.dynamsoft.dbr.*;
    
  3. Initialize the license.

    BarcodeReader.initLicense("DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="); //one-day trial
    

    You can apply for a license key from the customer portal of Dynamsoft.

  4. Create an instance of Dynamsoft Barcode Reader.

    BarcodeReader reader = new BarcodeReader();
    
  5. Read barcodes from an image file and print the results.

    String image_path = "test.jpg";
    TextResult[] results = reader.decodeFile(path, "");
    for (TextResult result:results) {
        System.out.println(result.barcodeFormatString+": "+result.barcodeText);
    }
    

    Output example:

    QR_CODE: https://www.dynamsoft.com/
    QR_CODE: Dynamsoft Barcode Reader SDK saves you months of added development time and extra costs
    

You can learn more about its usage in the docs.

Make the App Work as a Web Server

Next, let’s make it a web server to provide a web API for reading barcodes from images.

Create a new HTTPServlet to Read Barcodes

We need to create an HTTPServlet which receives an image encoded in JSON and responds with the barcode reading results in JSON.

Request example:

{
  "base64":"<base64-encoded image>"
}

Response example:

{
  "elapsedTime":20,
  "results": [
    "barcodeText":"example",
    "barcodeFormat":"QR_CODE",
    "barcodeBytes":"",
    "x1":0,
    "x2":50,
    "x3":50,
    "x4":0,
    "y1":10,
    "y2":10,
    "y3":50,
    "y4":50
  ]
}
  1. Create a new class named BarcodeReadingServlet which extends HTTPServlet.

    public class BarcodeReadingServlet extends HttpServlet{}
    
  2. Add a doPost method to handle post requests.

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
    
  3. Get the JSON request body as string.

    StringBuilder sb = new StringBuilder();
    BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(request.getInputStream(), "UTF-8"));
    String line;
    while ((line = bufferedReader.readLine()) != null)
        sb.append(line);
    
  4. Define a DecodingRequestBody class and convert the JSON request body to an instance of it.

    public class DecodingRequestBody {
        public String base64;
    }
       
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //...
        Gson gson = new Gson();
        DecodingRequestBody body = gson.fromJson(sb.toString(), DecodingRequestBody.class);
    }
    
  5. Initialize an instance of Dynamsoft Barcode Reader to read barcodes from the base64-encoded image.

    BarcodeReader reader = new BarcodeReader();
    long startTime = System.nanoTime();
    TextResult[] results = reader.decodeBase64String(body.base64, "");
    long endTime = System.nanoTime();
    
  6. Create a new DecodingResult class for storing the barcode reading results and convert it to JSON.

    public class DecodingResult {
        public List<BarcodeResult> results;
        public long elapsedTime;
    }
       
    public class BarcodeResult {
        public String barcodeText;
        public String barcodeFormat;
        public String barcodeBytes;
        public int x1;
        public int x2;
        public int x3;
        public int x4;
        public int y1;
        public int y2;
        public int y3;
        public int y4;
    }
       
    //...
       
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //...
        List<BarcodeResult> barcodeResults = new ArrayList<BarcodeResult>();
        for (TextResult result:results) {
            BarcodeResult barcodeResult = new BarcodeResult();
            barcodeResult.barcodeText = result.barcodeText;
            barcodeResult.barcodeFormat = result.barcodeFormatString;
            barcodeResult.barcodeBytes = Base64.getEncoder().encodeToString(result.barcodeBytes);
            barcodeResult.x1 = result.localizationResult.resultPoints[0].x;
            barcodeResult.x2 = result.localizationResult.resultPoints[1].x;
            barcodeResult.x3 = result.localizationResult.resultPoints[2].x;
            barcodeResult.x4 = result.localizationResult.resultPoints[3].x;
            barcodeResult.y1 = result.localizationResult.resultPoints[0].y;
            barcodeResult.y2 = result.localizationResult.resultPoints[1].y;
            barcodeResult.y3 = result.localizationResult.resultPoints[2].y;
            barcodeResult.y4 = result.localizationResult.resultPoints[3].y;
            barcodeResults.add(barcodeResult);
        }
        decodingResult.elapsedTime = endTime - startTime;
        decodingResult.results = barcodeResults;
        String json = gson.toJson(decodingResult);
    }
    
  7. Write the JSON to the response.

    response.getWriter().write(json);
    

Start the App as a Server

Modify App.java to make the app start as a server.

  1. Create and configure a ThreadPool.

    QueuedThreadPool threadPool = new QueuedThreadPool();
    threadPool.setName("server");
    
  2. Create a Server instance.

    Server server = new Server(threadPool);
    
  3. Create a ServerConnector to accept connections from clients and add the Connector to the Server.

    ServerConnector connector = new ServerConnector(server);
    connector.setPort(51041);
    server.addConnector(connector);
    
  4. Create a ResourceHandler so that the server can serve static pages.

    ResourceHandler resourceHandler = new ResourceHandler();
    resourceHandler.setDirAllowed(true);
    resourceHandler.setResourceBase(".");
    
  5. Create a ServletHandler for the barcode reading HTTPServlet.

    ServletHandler servletHandler = new ServletHandler();
    servletHandler.addServletWithMapping(BarcodeReadingServlet.class, "/readBarcodes");
    
  6. Configure handlers.

    HandlerCollection handlerList = new HandlerCollection();
    handlerList.setHandlers(new Handler[]{resourceHandler,servletHandler});
    server.setHandler(handlerList);
    
  7. Start the server.

    server.start();
    

Have a Test

We can then write a command line script in Python to test the performance of the API server. It uses the multiprocessing package to simulate 100 requests made concurrently.

import base64
import requests
import json
import time
from multiprocessing import Process, Value

def get_picture_base64_data(image_path):
    with open(image_path, 'rb') as image_file:
        base64_data = base64.b64encode(image_file.read())
    return base64_data.decode('utf-8')

def decode(index, completed_number, success_number, files_number, start_time):
    base64 = get_picture_base64_data("../AllSupportedBarcodeTypes.png")
    body = {"base64": base64}
    json_data = json.dumps(body)
    headers = {'Content-type': 'application/json'}
    r = requests.post('http://127.0.0.1:51041/readBarcodes', data=json_data, headers=headers)
    completed_number.value = completed_number.value + 1
    if r.status_code == 200:
        success_number.value = success_number.value + 1
        print("success "+str(index))
    if completed_number.value == files_number.value:
        end_time = time.time()
        elapsed_time = int((end_time - start_time.value) * 1000)
        print("Successfully decoded " + str(success_number.value) + " images in " + str(elapsed_time) + "ms.")


if __name__ == "__main__":
    iteration_times = 100
    completed_number = Value('d', 0.0)
    success_number = Value('d', 0.0)
    files_number = Value('d', iteration_times)
    start_time = Value('d', time.time())
    for i in range(iteration_times):
        p = Process(target=decode, args=(i, completed_number, success_number, files_number, start_time))
        p.start()

Output:

...
success 66
success 97
success 35
Successfully decoded 100.0 images in 12978ms.

HTML Front-End

With the back-end server, we can now add a basic front-end to consume the API and add the results to the DOM via AJAX. We are not going to cover this in detail. You can check out the source code in the GitHub repo.

Front-End

Source Code

The source code of the project is available here: https://github.com/tony-xlh/Barcode-Reading-Server-Java/