Form Validation in Java Servlet

Form Validation in Java Servlet | Verifying the pattern and format of form data before it is getting used in the business logic as inputs are called form validations, otherwise business logic may give invalid results or exceptions by taking the inputs. Example:- Checking required fields of the form are filled or not, checking whether age types as a numeric value and e.t.c.

Difference between form validation logic and business logic? In form validation logic, the pattern and format of the form data will be verified. Whereas business logic/request processing logic takes form data as inputs and uses them to process the request and generate the results. Example:-

Form Validation ExamplesBusiness Logic Examples
Credit card number is having 16 digits or not? (format verification)Credit card number is existing or a valid number?
The given date value is in MM/DD/YYYY pattern or not? (Pattern verification)Getting sales report for given data value.
Whether age is entered as a number or not, and it is in the range of 1 to 150?Checking whether the person is eligible to vote or not based on the given age.

Form validation logic in web application

Client SideServer Side
Place JavaScript code as form validation logic.Place Java code as form validation logic.
Executes in browser by coming browser along with form page.Always resides and executes in the server by becoming part of servlet component code.

Different Approach to Place Form Validation Logic

Approach1:- Placing form validation logic only in server side.

If we place only server-side form validation logic, then the network round trips between the client(browser) and the server will be increased if the form page is rejected by the server multiple times.

Approach2:- Placing form validation logic only in client side.

Pros:- If we place only client-side form validation logic (JavaScript) then it reduces the network round trips between client and server because the form validation takes place on the client-side itself without going to the server. 

Cons:- There is a possibility of disabling script execution using browser settings. By disabling the script, the client can give the wrong data. The script can also be disabled by using storms. In this way, wrong values will be stored in the database.

Approach3:- Placing form validation logic both on the server-side and client-side.

Pros:- Write both client and server-side validation logics, so the server-side form validation takes place even though client-side form validation is not done.

Cons:- If client-side form validation is performed then it will also perform server-side form validation which degrades the performance.

Approach4:- Place form validation logic both in server-side and client-side, but execute server-side form validation logic only when client-side form validation logic is not executed.

Write both client-side and server-side form validations, but enable server-side form validations only when client-side form validations are not done. This client(browser) sends a flag to the server indicating whether client-side form validations are done or not.

Conclusion:- Approach-4 is the best approach. Compared to the other approach, approach-4 doesn’t have a performance issue because the server-side will execute only when client-side form validations are not done.

How we will discuss them here? Our main focus is learning the fourth approach. But if you observe it then to learn the fourth approach, first we have to learn the first, second, and third approach. The fourth approach is internally using the first, second, and third approaches. Therefore we will discuss them one by one, with examples of the web applications.

Simple Application without Form Validation

Let us first see a simple Java servlet web application without using any form validation. After developing this application we will enhance it with server-side, and client-side form validation logic. We will use HTML to Servlet communication using Forms.

Web application description:- We will develop a simple Java-servlet-based web application that contains an HTML form to take name and age as input from the user. Based on the input data servlet component finds whether the user is eligible for voting or not.

The main component in this web application will be:- input.html, CheckVoterServlet.java, and web.xml file.

The input.html file,

<body>
  <h1 style="text-align:center; color:blue">Election Commission</h1>
  <div>
    <form action="checkvoter" method="post">
      <table style="background-color: #E4E4E4">
        <tr>
          <td>Name::</td>
          <td><input type="text" name="pname"></td>
        </tr>
        <tr>
          <td>Age::</td>
          <td><input type="password" name="page"></td>
        </tr>
        <tr>
          <td><input type="submit" value="Check Voting Eligibility"></td>
          <td><input type="reset" value="Cancel"></td>
        </tr>
      </table>
    </form>
  </div>
</body>
input html form

The servlet component (CheckVoterServlet.java),

package com.kp.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class CheckVoterServlet extends HttpServlet {
  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException {
    // variables
    PrintWriter pw = null;
    String name = null;
    String tage = null;
    int age = 0;
    
    // set content type
    resp.setContentType("text/html");
    
    // get writer
    pw = resp.getWriter();
    
    // get form data
    name = req.getParameter("pname");
    tage = req.getParameter("page");
    // convert tage to number
    age = Integer.parseInt(tage);
    
    // welcome message
    pw.println("<h1 style='text-align:center'>"+
           "Election Commission</h1>");
    
    // business logic
    if(age >= 18) {
      pw.println("<h2 style='text-align:center; color: green'>"+
             "Hello, " + name + " Congratulations! <br>" +
             "You are eligible for voting.</h2>"
            );
    } else {
      pw.println("<h2 style='text-align:center; color: red'>"+
             "Hello, " + name + "<br>" +
             "Sorry, You are not eligible for voting.<br>"+
             "Please wait more " + (18-age) + " years.</h2>"
            );
    }
    
    // link to home
    pw.println("<h4><a href='input.html'>Home</a></h4>");
    
    // close stream
    pw.close();
  }
  
  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException {
    doPost(req, resp);
  }
}

The deployment descriptor (web.xml) file,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xsi:schemaLocation=
  "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  id="WebApp_ID" version="4.0">
  <display-name>ElectionCommission</display-name>
  <welcome-file-list>
    <welcome-file>input.html</welcome-file>
  </welcome-file-list>

  <servlet>
    <servlet-name>voting</servlet-name>
    <servlet-class>com.kp.servlet.CheckVoterServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>voting</servlet-name>
    <url-pattern>/checkvoter</url-pattern>
  </servlet-mapping>
</web-app>

See the source code of this web application (developed in Eclipse) at GitHub. You will get a similar result as the below image.

Eligible for voting
Not eligible for voting

Form Validation Logic for Above Java Web Application

The above application has some limitations, which can give 405 errors or unexpected results. For example, if you click on “check voting eligibility” without any input then we will get HTTP Status 500 – Internal Server Error with exception message java.lang.NumberFormatException: For input string: “”. The end-user may not be a technical person which can understand these Java error messages, therefore it is better to display some meaningful end-user understand messages.

We should perform the following form validation in above Java web application:-

  1. The name must be valid. It should not be null (not filled), or empty (only spaces), and the length of the name should not be lesser than 5 characters.
  2. Age must be valid. It should not be null (not filled), or empty( only spaces), and the length of the name should not be zero.
  3. The age should be in numeric format, (not in words, or special characters).
  4. The age should not be less than 0 and greater than 125

If the form is invalid then don’t process the business logic, simply give error message to the end user.

Server Side Form Validation Logic

Now let us see how to develop a Java web application with Server Side Form validation logic. In this application, no need to modify the input.html and web.xml file. Only the servlet component will be modified. Add the following logic in the servlet component before business logic.

// get form data
name = req.getParameter("pname");
tage = req.getParameter("page");

/* Server side form validation logic */
// Validate name
if(name == null || name.length()==0 || name.equals(" ")) {
   // " " => empty string
   pw.println("<h4 style='color:red'>Person name is required.</h4>");
   return; // stop execution
} else if(name.length() <= 5){
   pw.println("<h4 style='color:red'>"+
              "Person name must have minimum 5 Characters.</h4>");
   return; // stop execution
}

// Validate age
if(tage == null || tage.length() == 0 || tage.equals(" ")) {
   pw.println("<h4 style='color:red'>Person age is required.</h4>");
   return; // stop execution
} else {
   try {
      // if age is not numeric throw exception  
      age = Integer.parseInt(tage);
      // check age is valid or not
      if (age <= 0 || age >= 125) {
         pw.println("<h4 style='color:red'>"+
                    "Person age must be between 1 to 125.</h4>");
         return; // stop execution
      }
   } catch(NumberFormatException nfe) {
      pw.println("<h4 style='color:red'>Person age must be numeric.</h4>");
      return; // stop execution
   }
}

// business logic
// remaining logic

This time if you click “check voting eligibility” without any input then you won’t get error-500 rather you will get a meaningful message.

Why we used return; statements? When the form is invalid then we should not execute the business logic, so we display the error msg and return it. The return; gives control back to the caller method, and execution will be stopped.

The above code is correct, but don’t give all errors at a time. Here each error comes one by one, for example:- For no input, it will only display “person name is required”, but we also didn’t enter the personage. If you want to display all errors at a time then use the ArrayList collection. 

For this, we need to import the following two packages. In Ecplise to import the packages, you can use the CTRL+Shift+O key.

import java.util.ArrayList;
import java.util.List;

Declare a variable to store error messages,

List<String> errList = null;

The form validation logic,

// get form data
name = req.getParameter("pname");
tage = req.getParameter("page");

/* Server side form validation logic */
errList = new ArrayList<String>();

// name validation logic
if(name == null || name.length()==0 || name.equals(" ")) {
   errList.add("Person name is required");
}else if(name.length() <= 5){
   errList.add("Person name must have minimum 5 Characters.");
}

// age validation logic
if(tage == null || tage.length() == 0 || tage.equals(" ")) {
   errList.add("Person age is required");
} else {
   try {
       age = Integer.parseInt(tage);
       // check age is valid or not
       if (age <= 0 || age >= 125) {
          errList.add("Person age must be between 1 to 125.");
       }
    } catch(NumberFormatException nfe) {
       errList.add("Person age must be numeric value.");
    }
}

// display form validation error messages
if(errList.size() != 0) {
   for (String errMsg : errList) {
      pw.println("<li><span style='color:red'>" + errMsg + "</span></li>");
   }
   return; // stop
}

// business logic
// remaining logic

See the source code of this web application (developed in Eclipse) at GitHub. This time you will get all the error messages at once.

Client-Side Form Validation 

Now, we will see only the client-side form validation logic for the previous Java web application. HTML5 is also supplying some form validation rules like required, min, max, max length, and e.t.c. For example:-

Form Validation using HTML5

<input type="text" name="pname" required="required" maxlength="20">
<input type="password" name="page" required="required" min="1" max="125">
Client Side Form Validation using HTML  For Java Web Application

Working with HTML supplied form validation logic having following limitations,

  • Very few form validations are available.
  • We can’t customize form validation error messages.
  • Writing some validation logic through JavaScript and some logic through HTML5 doesn’t look good. 

We can write JavaScript code directly in HTML file as <script> tag before </head> tag, but anyone can see those code in browser through view page source (Ctrl+U). Therefore it is not recommended to write JavaScript code in the HTML file itself. To improve the reusability of JavaScript code across the multiple webpages given by different components and to hide the JavaScript code source visibility from the browser’s view resource options,  it is recommended to place JavaScript code in a file (generally we use “js” as a file name) and link that file to multiple web components.

webcontent
   |=> input.html
   |=> js
      |=> validation.js

Client side form validation in marriage application input.html form page using JavaScript

  • Person name is required.
  • Person’s name must have a minimum of 5 characters.
  • Personage is required.
  • Personage must be a numeric value
  • Personage must be there between 1 to 125.

To define function in JavaScript,

function<function-name> (parameters, … ) {
  ...
}

To define variables in JavaScript,

var <variablename>;
or
let <variablename>;

Parameter data types and variable data types will be decided dynamically based on the values that are assigned. No return type is required for the function but the function can return any value.

The simple JavaScript code (validation.js) for the form validation,

function validate(frm) {
   // read form data
   let name = frm.pname.value;
   let age = frm.page.value;
   let flag = true;
   
   // client side form validation logic
   if(name==""){
      alert("Person name is required");
      frm.pname.focus(); // focus the text box
      flag = false;
   } else if(name.length < 5) { // min length
      alert("Person name must have minimum of 5 Characters");
      frm.pname.focus(); // focus the text box
      flag = false;
   }
   if(age==""){
      alert("Person age is required");
      frm.page.focus(); // focus the text box
      flag = false;
   } else if(isNaN(age)) { // must be numeric
      alert("Person age is not a number");
      frm.page.focus(); // focus the text box
      flag = false;
   } else if(age<1 || age>125) { // age range 
      alert("Person age must be between 1 to 125");
      frm.page.focus(); // focus the text box
      flag = false;
   }
   return flag;
   // true => form is error free
   // false => form validation errors
}

In HTML file the JavaScript file is used through <script> tag,

<head>
   <script type="text/javascript" src="js/validation.js">
   </script>
</head>

In HTML file the function is called as,

<form action="checkvoter" method="post" onsubmit="return validate(this)">

Why we used return; statements? When the form is invalid then we should not execute the business logic, so we display the error msg and return it. The return; gives control back to the caller method, and execution will be stopped.

The HTML file (input.html),

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="js/validation.js">
</script>
</head>
<body>
  <h1 style="text-align: center; color: blue">Election Commission</h1>
  <div>
    <form action="checkvoter" method="post" onsubmit="return validate(this)">
      <table style="background-color: #E4E4E4">
        <tr>
          <td>Name::</td>
          <td><input type="text" name="pname"></td>
        </tr>
        <tr>
          <td>Age::</td>
          <td><input type="password" name="page"></td>
        </tr>
        <tr>
          <td><input type="submit" value="Check Voting Eligibility"></td>
          <td><input type="reset" value="Cancel"></td>
        </tr>
      </table>
    </form>
  </div>
</body>
</html>

See the source code for this application at GitHub. For invalid input, you will get a similar result as given in the image,

Simple JavaScript Error Message

In the above application, the error msg came into the screen and it blocks the entire form. Therefore, it is not the better approach. We should write a JavaScript file such as it shouldn’t block the entire screen.

We can use document.getElementById() method to display the error message within the same line. It won’t block the entire document. We can replace the code of the above validation.js file with the below code,

function validate(frm) {
  //read from data
  var name = frm.pname.value;
  var age = frm.page.value;

  // write client side form validation logic
  if (name == "") {
    document.getElementById("pnameErr").innerHTML =
      "<b>Person name is required</b>";
    frm.pname.focus();
    return false;
  }
  if (age == "") {
    document.getElementById("pageErr").innerHTML =
      "<b>Person age is required</b>";
    frm.page.focus();
    return false;
  } else if (isNaN(age)) {
    document.getElementById("pageErr").innerHTML =
      "<b>Person age must be numeric value</b>";
    frm.page.focus();
    return false;
  } else {
    if (age <= 0 || age > 125) {
      document.getElementById("pageErr").innerHTML =
        "<b>Person age must be between 1 to 125</b>";
      frm.page.focus();
      return false;
    }
  }
  return true;
}

In HTML file add span tag with name and age. Use id from the validation.js file.

<head>
<script type="text/javascript" src=js/validation.js>
</script>
</head>
<body>
  <div style='text-align: center'>
    <h1 style='color: blue'>Election Commission</h1>
    <form action="checkvoter" method="post" 
           onsubmit="return validate(this)">
      Name: <input type="text" name="pname"><span
        style="color: red" id="pnameErr"></span><br><br>
      Age: <input type="password" name="page"><span
        style="color: red" id="pageErr"></span><br><br> 
      <input type="submit" value="Check Voting eligibility">
      <input type="reset" value="Cancel">
    </form>
  </div>
</body>

See the source code for this application at GitHub.  

Problem with above form validation.js:- After the error message if we pass the right value then also it displays the previous error message. But it should not display the error message after giving the right input. 

JavaScript with getElementById - Form validation in Java web app

To solve this problem, add these lines before or after reading the form data in the validation.js.

document.getElementById("pnameErr").innerHTML="";
document.getElementById("pageErr").innerHTML="";
JavaScript with getElementById solution - Form validation in Java Web App

The drawback of Writing Form Validation Logic only in Client-Side

The JavaScript code can be blocked through browser settings, viruses, storms, and e.t.c. If JavaScript is blocked in the browser then the user can send the wrong input value. Since the form validation logic is not written on the server-side, therefore, the client-side form validation logic becomes useless. 

To visualize how it works:- disable the JavaScript code in your browser and again run the above web application. How to block JavaScript code in the chrome web browser?

  • In Google chrome browser software => Go to Settings => In “Privacy and security” Section => Site Settings => JavaScript => Block the JavaScript.
  • In Firefox, type “about:config” in browser address bar => Click on “Accept the risk and continue” => Type “JavaScript” in the “Search” box => Double-click the “JavaScript.enabled” line to toggle the setting between “true” and “false” as desired.

After disabling the JavaScript in browser software, if we give a request to the servlet component without entering input then we will get an HTTP status code 500 error.

When JavaScript is blocked then we should inform the end-user with a msg saying “JavaScript is blocked in your web browser”. For this purpose, the <noscript> tag can be used. 

Using the <noscript> tag, we can pass guiding messages to the end user through browser settings if it is disabled. Place <noscript> tag inside the body part of the HTML file. Example of <noscript> tag:-

<noscript>
  <span style="color:red">JavaScript is blocked, Enable the JavaScript</span>
</noscript>

The HTML file after placing the <noscript> tag:-

<head>
<script type="text/javascript" src=js/validation.js>
</script>
</head>
<body>
  <noscript>
    <span style="color: red">JavaScript is blocked, Enable the
      JavaScript</span>
  </noscript>
  <div style='text-align: center'>
    <h1 style='color: blue'>Election Commission</h1>
    <form action="checkvoter" method="post"
      onsubmit="return validate(this)">
      Name: <input type="text" name="pname"><span
        style="color: red" id="pnameErr"></span><br>
      <br> Age: <input type="password" name="page"><span
        style="color: red" id="pageErr"></span><br>
      <br> <input type="submit" value="Check Voting eligibility">
      <input type="reset" value="Cancel">
    </form>
  </div>
</body>

Now we will get a guiding message to enable JavaScript. The below image shows the current output.

JavaScript is disabled in browser - Form validation in Java web application

From Validation Logic in both Client and Server Side

If we combine the previous two approaches then you can achieve this approach where form validation logic is available at both the client-side and server-side. 

Advantage:- If the form validation logic is not executed on the client-side then it will definitely be executed on the server-side. Therefore, there is no chance for wrong data.

Disadvantage:- If the form is validated at the client-side then it will also be validated at the server-side, we are validating the same logic two times. Assume if the validation logic is of 5000 lines of codes, then those codes will be executed two times at different places. So, it is not a good approach.

From Validation Logic in both Client and Server Side but Validate at Server Side only if client-side validation not done

Write both client-side and server-side form validations, but enable server-side form validations only when client-side form validations are not done. This client(browser) sends a flag to the server indicating whether client-side form validations are done or not. 

For this purpose, we can use hidden boxes in the HTML form. By using hidden box support the form page can send a signal to the server or servlet component along with the request whether client-side JavaScript form validations are performed or not? If already performed at the client-side then don’t perform server-side form validations.

In HTML file inside the <form> tag,

<form>
   <!-- hidden box -->
   <input type="hidden" name="vflag" value="no">
</form>

In JavaScript file, inside the function,

function validate(frm) {
   // set vflag value to "yes" indicating
   // client side form validations are done
   frm.vflag.value = "yes";

   // remaining logic
}

In the Servlet component, read form that data and check the value of flag,

// variable
String vstatus = null;

// get client side form validation status
vstatus = req.getParameter("vflag"); 

if(vstatus.equals("no")) { 
   /* If client side validations are not done,
    * then only perform server side validations.
    */

   // server side form validation logic

} else { 
   // when client side form validation are done
   age = Integer.parseInt(tage);
}

See the source code for this application at GitHub. Now, if the JavaScript is disabled on the client-side then server-side form validation logic will be executed. And there will be no chance to get the wrong input value from the end-user.

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!

Leave a Comment

Your email address will not be published. Required fields are marked *