Create a Simple Java Web Application Using Servlet, JSP and JDBC

1- Introduction

This document is based on:
  • Eclipse 4.5 MARS (ok for Eclipse 4.4 LUNA)

  • Tomcat 8.x

Document History:
  • 12-12-2014: JSP + Servlet + Filter + JSTL
  • 06-08-2015: JSP + Servlet + Filter + JSTL + JDBC
In this document, I will guide step by step how to create a simple web application with the combiantion of  Servlet + JSP Filter JSP EL + JDBC. Make sure that you've mastered  Servlet, JSP and  Filter and  JDBC before the start. If not, you can refer to:

Servlet:

Filter:

JSP:

JSP Standard Tag Libs (JSTL)

JDBC

2- The principle when programming Servlet + JSP

These are the principles that you should keep in mind to be able to build a Web application using   Servlet + JSP  satisfying criteria: code is simple, easy to understand and easy to maintain.
The principles:
  1. Never allow users to directly access to your JSP page.
  2. JSP is only considered as the place to display interface.
  3. Servlet acts as the controller of the application flows and  program logical processing.
  4. Open the JDBC connection and transaction management in Filter (Optional).

According to the principle 1:

Never allow users to directly access to your JSP page, it means that all user's requests are:
  • Another source of static data (images, css, js, ...)
  • Or a servlet.
Therefore, you must hide your JSP files in a place where the user can not access. For instance, set it in the WEB-INF folder or its subdirectories. In this example, I hide the jsp files in the WEB-INF/views.
When the user  requests  to a Servlet, it will dispose user's requirements, such insert, update and query the data, eventually forward to the JSP page to display the data. Thus,  each servlet has 0 or multiple corresponding JSP pages (Usually only need 1).

Principle 2:

JSP is only considered as the place to display data, which means that you should not handle the application logic on the JSP, such as update, insert, delete, .., and not navigate on the JSP page.

3- View Demo of Web Application will do

You can preview Demo Web application will do:

4- Prepare database

In this document, I instruct you to work with one of 3 databases: Oracle, MySQL or SQL Server. You need to run scripts to create some tables and necessary data for this example.

ORACLE:

-- Create table
create table USER_ACCOUNT
(
USER_NAME VARCHAR2(30) not null,
GENDER    VARCHAR2(1) not null,
PASSWORD  VARCHAR2(30) not null,
primary key (USER_NAME)
);

-- Create table
create table PRODUCT
(
CODE  VARCHAR2(20) not null,
NAME  VARCHAR2(128) not null,
PRICE FLOAT not null,
primary key (CODE)
) ;

-- Insert data: ---------------------------------------------------------------

insert into user_account (USER_NAME, GENDER, PASSWORD)
values ('tom', 'M', 'tom001');

insert into user_account (USER_NAME, GENDER, PASSWORD)
values ('jerry', 'M', 'jerry001');

insert into product (CODE, NAME, PRICE)
values ('P001', 'Java Core', 100);

insert into product (CODE, NAME, PRICE)
values ('P002', 'C# Core', 90);

-- Commit
Commit;

MYSQL:

-- Create table
create table USER_ACCOUNT
(
USER_NAME VARCHAR(30) not null,
GENDER    VARCHAR(1) not null,
PASSWORD  VARCHAR(30) not null,
primary key (USER_NAME)
);

-- Create table
create table PRODUCT
(
CODE  VARCHAR(20) not null,
NAME  VARCHAR(128) not null,
PRICE FLOAT not null,
primary key (CODE)
) ;

-- Insert data: ---------------------------------------------------------------

insert into user_account (USER_NAME, GENDER, PASSWORD)
values ('tom', 'M', 'tom001');

insert into user_account (USER_NAME, GENDER, PASSWORD)
values ('jerry', 'M', 'jerry001');

insert into product (CODE, NAME, PRICE)
values ('P001', 'Java Core', 100);

insert into product (CODE, NAME, PRICE)
values ('P002', 'C# Core', 90);

SQL SERVER:

-- Create table
create table USER_ACCOUNT
(
USER_NAME VARCHAR(30) not null,
GENDER    VARCHAR(1) not null,
PASSWORD  VARCHAR(30) not null,
primary key (USER_NAME)
);

-- Create table
create table PRODUCT
(
CODE  VARCHAR(20) not null,
NAME  VARCHAR(128) not null,
PRICE FLOAT not null,
primary key (CODE)
) ;

-- Insert data: ---------------------------------------------------------------

insert into user_account (USER_NAME, GENDER, PASSWORD)
values ('tom', 'M', 'tom001');

insert into user_account (USER_NAME, GENDER, PASSWORD)
values ('jerry', 'M', 'jerry001');

insert into product (CODE, NAME, PRICE)
values ('P001', 'Java Core', 100);

insert into product (CODE, NAME, PRICE)
values ('P002', 'C# Core', 90);

5- Create WebApp Project

In Eclipse select:
  • File/New/Other...
Project was created.
Add index.html
index.html
<!DOCTYPE html>
<html>
  <head>
     <meta charset="UTF-8">
     <title>Simple Web Application</title>
  </head>
 
  <body>
 
     <h2>Simple Login Web Application using JSP/Servlet</h2>
     
     <ul>
        <li><a href="home">Home</a></li>
        <li><a href="login">Login</a></li>
        <li><a href="productList">Product  List</a>
     </ul>
     
  </body>
</html>

6- Configuring the runtime environment

The application needs to run on a WebServer,  such as  Tomcat Server, you can refer to download and declaration instructions of  Server Tomcat in  Eclipse at:
Right-click the SimpleWebApp select Properties.

7- Run application for first time

Right-click on SimpleWebApp, select:
  • Run As/Run on Server
Application has been run:
OK, here everything is fine. We'll start programming a real Web application.

8- Download and declare JDBC library

You have to download JDBC library to driving the connection with the Database. In this document, I download both of 3  JDBC libraries for Oracle, MySQL, SQL Server, in practice, you only need JDBC library corresponding to the type of database you are using.
You can see download instruction of JDBC driver at:
Or download here:
Results downloaded:
Copy these libraries into the WEB-INF/lib:

9- Download and declare JSTL library

You need to download 2 JSTL libraries to be able to use them in the JSP:
  • javax.servlet.jsp.jstl-*.jar
  • javax.servlet.jsp.jslt-api-*.jar
Copy 2 jar files that you just downloaded into the / WEB-INF/lib:

10- Javabean classes simulated tables in the database

Create 2 JavaBean classes, wherein each class simulated a table in the database:
UserAccount.java
package org.o7planning.simplewebapp.beans;

public class UserAccount {

   public static final String GENDER_MALE ="M";
   public static final String GENDER_FEMALE = "F";
   
   private String userName;
   private String gender;
   private String password;
   

   public UserAccount() {
       
   }
   
   public String getUserName() {
       return userName;
   }

   public void setUserName(String userName) {
       this.userName = userName;
   }

   public String getGender() {
       return gender;
   }

   public void setGender(String gender) {
       this.gender = gender;
   }

   public String getPassword() {
       return password;
   }

   public void setPassword(String password) {
       this.password = password;
   }

}
Product.java
package org.o7planning.simplewebapp.beans;

public class Product {

   private String code;
   private String name;
   private float price;

   public Product() {

   }

   public Product(String code, String name, float price) {
       this.code = code;
       this.name = name;
       this.price = price;
   }

   public String getCode() {
       return code;
   }

   public void setCode(String code) {
       this.code = code;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public float getPrice() {
       return price;
   }

   public void setPrice(float price) {
       this.price = price;
   }

}

11- Database Connection Utility classes

MySQLConnUtils.java
package org.o7planning.simplewebapp.conn;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class MySQLConnUtils {

public static Connection getMySQLConnection()
        throws ClassNotFoundException, SQLException {
 
    // Note: Change the connection parameters accordingly.
    String hostName = "localhost";
    String dbName = "mytest";
    String userName = "root";
    String password = "12345";
    return getMySQLConnection(hostName, dbName, userName, password);
}

public static Connection getMySQLConnection(String hostName, String dbName,
        String userName, String password) throws SQLException,
        ClassNotFoundException {
   
    // Declare the class Driver for MySQL DB
    // This is necessary with Java 5 (or older)
    // Java6 (or newer) automatically find the appropriate driver.
    // If you use Java> 5, then this line is not needed.
    Class.forName("com.mysql.jdbc.Driver");


    // URL Connection for MySQL
    // Example: jdbc:mysql://localhost:3306/simplehr
    String connectionURL = "jdbc:mysql://" + hostName + ":3306/" + dbName;

    Connection conn = DriverManager.getConnection(connectionURL, userName,
            password);
    return conn;
}
}
OracleConnUtils.java
package org.o7planning.simplewebapp.conn;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class OracleConnUtils {

  public static Connection getOracleConnection()
          throws ClassNotFoundException, SQLException {
     
      // Note: Change the connection parameters accordingly.
      String hostName = "localhost";
      String sid = "db11g";
      String userName = "mytest";
      String password = "12345";

      return getOracleConnection(hostName, sid, userName, password);
  }

  public static Connection getOracleConnection(String hostName, String sid,
          String userName, String password) throws ClassNotFoundException,
          SQLException {

     
      // Declare the class Driver for ORACLE DB
      // This is necessary with Java 5 (or older)
      // Java6 (or newer) automatically find the appropriate driver.
      // If you use Java> 5, then this line is not needed.        
      Class.forName("oracle.jdbc.driver.OracleDriver");


      // URL Connection for Oracle
      // Example: jdbc:oracle:thin:@localhost:1521:db11g
      String connectionURL = "jdbc:oracle:thin:@" + hostName + ":1521:" + sid;

      Connection conn = DriverManager.getConnection(connectionURL, userName,
              password);
      return conn;
  }
}
SQLServerConnUtils_JTDS.java
package org.o7planning.simplewebapp.conn;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class SQLServerConnUtils_JTDS {

   
 // Connect to SQLServer
 // (Using JDBC Driver of JTDS library)    
 public static Connection getSQLServerConnection_JTDS() throws SQLException,
         ClassNotFoundException {
   
     // Note: Change the connection parameters accordingly.
     
     String hostName = "localhost";
     String sqlInstanceName = "SQLEXPRESS";
     String database = "mytest";
     String userName = "sa";
     String password = "12345";

     return getSQLServerConnection_JTDS(hostName, sqlInstanceName, database,
             userName, password);
 }


 // Connect to SQLServer, using JTDS library  
 private static Connection getSQLServerConnection_JTDS(String hostName,
         String sqlInstanceName, String database, String userName,
         String password) throws ClassNotFoundException, SQLException {
   
     // Declare the class Driver for SQLServer DB
     // This is necessary with Java 5 (or older)
     // Java6 (or newer) automatically find the appropriate driver.
     // If you use Java> 5, then this line is not needed.  
     Class.forName("net.sourceforge.jtds.jdbc.Driver");

   
     // Example:
     // jdbc:jtds:sqlserver://localhost:1433/simplehr;instance=SQLEXPRESS
     String connectionURL = "jdbc:jtds:sqlserver://" + hostName + ":1433/"
             + database + ";instance=" + sqlInstanceName;

     Connection conn = DriverManager.getConnection(connectionURL, userName,
             password);
     return conn;
 }

}
SQLServerConnUtils_SQLJDBC.java
package org.o7planning.simplewebapp.conn;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class SQLServerConnUtils_SQLJDBC {

 
 // Connect to SQLServer
 // (Using JDBC Driver: SQLJDBC)    
 public static Connection getSQLServerConnection_SQLJDBC()
         throws ClassNotFoundException, SQLException {
     
     // Note: Change the connection parameters accordingly.
     
     String hostName = "localhost";
     String sqlInstanceName = "SQLEXPRESS";
     String database = "mytest";
     String userName = "sa";
     String password = "12345";

     return getSQLServerConnection_SQLJDBC(hostName, sqlInstanceName,
             database, userName, password);
 }



 //Connect to SQLServer, using SQLJDBC Library.
 private static Connection getSQLServerConnection_SQLJDBC(String hostName,
         String sqlInstanceName, String database, String userName,
         String password) throws ClassNotFoundException, SQLException {
   
     // Declare the class Driver for SQLServer DB
     // This is necessary with Java 5 (or older)
     // Java6 (or newer) automatically find the appropriate driver.
     // If you use Java> 5, then this line is not needed.        
     Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

     // jdbc:sqlserver://ServerIp:1433/SQLEXPRESS;databaseName=simplehr      
     String connectionURL = "jdbc:sqlserver://" + hostName + ":1433"
             + ";instance=" + sqlInstanceName + ";databaseName=" + database;

     Connection conn = DriverManager.getConnection(connectionURL, userName,
             password);
     return conn;
 }

}
ConnectionUtils.java
package org.o7planning.simplewebapp.conn;

import java.sql.Connection;
import java.sql.SQLException;

public class ConnectionUtils {

   public static Connection getConnection()
             throws ClassNotFoundException, SQLException {
     
       // Here I using Oracle Database.
       return OracleConnUtils.getOracleConnection();
       
       // return MySQLConnUtils.getMySQLConnection();
       // return SQLServerConnUtils_JTDS.getSQLServerConnection_JTDS();
       // return SQLServerConnUtils_SQLJDBC.getSQLServerConnection_SQLJDBC();
   }
   
   public static void closeQuietly(Connection conn) {
       try {
           conn.close();
       } catch (Exception e) {
       }
   }

   public static void rollbackQuietly(Connection conn) {
       try {
           conn.rollback();
       } catch (Exception e) {
       }
   }
}

12- The utility class & manipulate data

MyUtils.java
package org.o7planning.simplewebapp.utils;

import java.sql.Connection;

import javax.servlet.ServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.o7planning.simplewebapp.beans.UserAccount;

public class MyUtils {

   public static final String ATT_NAME_CONNECTION = "ATTRIBUTE_FOR_CONNECTION";

   private static final String ATT_NAME_USER_NAME = "ATTRIBUTE_FOR_STORE_USER_NAME_IN_COOKIE";

   
   // Store Connection in request attribute.
   // (Information stored only exist during requests)
   public static void storeConnection(ServletRequest request, Connection conn) {
       request.setAttribute(ATT_NAME_CONNECTION, conn);
   }

   // Get the Connection object has been stored in one attribute of the request.
   public static Connection getStoredConnection(ServletRequest request) {
       Connection conn = (Connection) request.getAttribute(ATT_NAME_CONNECTION);
       return conn;
   }

   // Store user info in Session.
   public static void storeLoginedUser(HttpSession session, UserAccount loginedUser) {

       // On the JSP can access ${loginedUser}
       session.setAttribute("loginedUser", loginedUser);
   }


   // Get the user information stored in the session.
   public static UserAccount getLoginedUser(HttpSession session) {
       UserAccount loginedUser = (UserAccount) session.getAttribute("loginedUser");
       return loginedUser;
   }


   // Store info in Cookie
   public static void storeUserCookie(HttpServletResponse response, UserAccount user) {
       System.out.println("Store user cookie");
       Cookie cookieUserName = new Cookie(ATT_NAME_USER_NAME, user.getUserName());

       // 1 day (Convert to seconds)
       cookieUserName.setMaxAge(24 * 60 * 60);
       response.addCookie(cookieUserName);
   }

   public static String getUserNameInCookie(HttpServletRequest request) {
       Cookie[] cookies = request.getCookies();
       if (cookies != null) {
           for (Cookie cookie : cookies) {
               if (ATT_NAME_USER_NAME.equals(cookie.getName())) {
                   return cookie.getValue();
               }
           }
       }
       return null;
   }


   // Delete cookie.
   public static void deleteUserCookie(HttpServletResponse response) {
       Cookie cookieUserName = new Cookie(ATT_NAME_USER_NAME, null);

       // 0 seconds (Expires immediately)
       cookieUserName.setMaxAge(0);
       response.addCookie(cookieUserName);
   }

}
DBUtils.java
package org.o7planning.simplewebapp.utils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.o7planning.simplewebapp.beans.Product;
import org.o7planning.simplewebapp.beans.UserAccount;

public class DBUtils {

  public static UserAccount findUser(Connection conn, String userName, String password) throws SQLException {

      String sql = "Select a.User_Name, a.Password, a.Gender from User_Account a "
              + " where a.User_Name = ? and a.password= ?";

      PreparedStatement pstm = conn.prepareStatement(sql);
      pstm.setString(1, userName);
      pstm.setString(2, password);
      ResultSet rs = pstm.executeQuery();

      if (rs.next()) {
          String gender = rs.getString("Gender");
          UserAccount user = new UserAccount();
          user.setUserName(userName);
          user.setPassword(password);
          user.setGender(gender);
          return user;
      }
      return null;
  }

  public static UserAccount findUser(Connection conn, String userName) throws SQLException {

      String sql = "Select a.User_Name, a.Password, a.Gender from User_Account a " + " where a.User_Name = ? ";

      PreparedStatement pstm = conn.prepareStatement(sql);
      pstm.setString(1, userName);

      ResultSet rs = pstm.executeQuery();

      if (rs.next()) {
          String password = rs.getString("Password");
          String gender = rs.getString("Gender");
          UserAccount user = new UserAccount();
          user.setUserName(userName);
          user.setPassword(password);
          user.setGender(gender);
          return user;
      }
      return null;
  }

  public static List<Product> queryProduct(Connection conn) throws SQLException {
      String sql = "Select a.Code, a.Name, a.Price from Product a ";

      PreparedStatement pstm = conn.prepareStatement(sql);

      ResultSet rs = pstm.executeQuery();
      List<Product> list = new ArrayList<Product>();
      while (rs.next()) {
          String code = rs.getString("Code");
          String name = rs.getString("Name");
          float price = rs.getFloat("Price");
          Product product = new Product();
          product.setCode(code);
          product.setName(name);
          product.setPrice(price);
          list.add(product);
      }
      return list;
  }

  public static Product findProduct(Connection conn, String code) throws SQLException {
      String sql = "Select a.Code, a.Name, a.Price from Product a where a.Code=?";

      PreparedStatement pstm = conn.prepareStatement(sql);
      pstm.setString(1, code);

      ResultSet rs = pstm.executeQuery();

      while (rs.next()) {
          String name = rs.getString("Name");
          float price = rs.getFloat("Price");
          Product product = new Product(code, name, price);
          return product;
      }
      return null;
  }

  public static void updateProduct(Connection conn, Product product) throws SQLException {
      String sql = "Update Product set Name =?, Price=? where Code=? ";

      PreparedStatement pstm = conn.prepareStatement(sql);

      pstm.setString(1, product.getName());
      pstm.setFloat(2, product.getPrice());
      pstm.setString(3, product.getCode());
      pstm.executeUpdate();
  }

  public static void insertProduct(Connection conn, Product product) throws SQLException {
      String sql = "Insert into Product(Code, Name,Price) values (?,?,?)";

      PreparedStatement pstm = conn.prepareStatement(sql);

      pstm.setString(1, product.getCode());
      pstm.setString(2, product.getName());
      pstm.setFloat(3, product.getPrice());

      pstm.executeUpdate();
  }

  public static void deleteProduct(Connection conn, String code) throws SQLException {
      String sql = "Delete Product where Code= ?";

      PreparedStatement pstm = conn.prepareStatement(sql);

      pstm.setString(1, code);

      pstm.executeUpdate();
  }

}

13- Create Filter connect to Database

In JDBCFilter, I checked which  requests actually referred to a Servlet, so that you can see the picture below to find it easy to understand, it describes the relationship between the concepts of Servlet.
JDBCFilter with url-pattern = /* means that all requests of users have go through this filter.
JDBCFilter will check the request to ensure that it only opens JDBC connection  for the necessary request, eg for Servlet, avoid opening JDBC connection to common requests like image, css, js, html
JDBCFilter.java
package org.o7planning.simplewebapp.filter;

import java.io.IOException;
import java.sql.Connection;
import java.util.Collection;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

import org.o7planning.simplewebapp.conn.ConnectionUtils;
import org.o7planning.simplewebapp.utils.MyUtils;

@WebFilter(filterName = "jdbcFilter", urlPatterns = { "/*" })
public class JDBCFilter implements Filter {

   public JDBCFilter() {
   }

   @Override
   public void init(FilterConfig fConfig) throws ServletException {

   }

   @Override
   public void destroy() {

   }


   // Check the target of the request is a servlet?
   private boolean needJDBC(HttpServletRequest request) {
       System.out.println("JDBC Filter");
       //
       // Servlet Url-pattern: /spath/*
       //
       // => /spath
       String servletPath = request.getServletPath();
       // => /abc/mnp
       String pathInfo = request.getPathInfo();

       String urlPattern = servletPath;

       if (pathInfo != null) {
           // => /spath/*
           urlPattern = servletPath + "/*";
       }

       // Key: servletName.
       // Value: ServletRegistration
       Map<String, ? extends ServletRegistration> servletRegistrations = request.getServletContext()
               .getServletRegistrations();


       // Collection of all servlet in your webapp.
       Collection<? extends ServletRegistration> values = servletRegistrations.values();
       for (ServletRegistration sr : values) {
           Collection<String> mappings = sr.getMappings();
           if (mappings.contains(urlPattern)) {
               return true;
           }
       }
       return false;
   }

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
           throws IOException, ServletException {

       HttpServletRequest req = (HttpServletRequest) request;


       //
       // Only open connections for the special requests need
       // connection. (For example, the path to the servlet, JSP, ..)
       //
       // Avoid open connection for commons request
       // (for example: image, css, javascript,... )
       //
       if (this.needJDBC(req)) {

           System.out.println("Open Connection for: " + req.getServletPath());

           Connection conn = null;
           try {
               // Create connection
               conn = ConnectionUtils.getConnection();

               // Set Auto commit to false
               conn.setAutoCommit(false);

                // Store connection in attribute of request.
               MyUtils.storeConnection(request, conn);

               // Allow request to go forward
               // (Go to the next filter or target)
               chain.doFilter(request, response);

                // Commit change.
               conn.commit();
           } catch (Exception e) {
               e.printStackTrace();
               ConnectionUtils.rollbackQuietly(conn);
               throw new ServletException();
           } finally {
               ConnectionUtils.closeQuietly(conn);
           }
       }

       // With commons requests (images, css, html, ..)
       // No need to open the connection.        
       else {

           // Allow request to go forward
           // (Go to the next filter or target)            
           chain.doFilter(request, response);
       }

   }

}

14- Cookie Filter

In case, the user logined and  remembered information in previous access (for example the day before). And now the user return, this Filter will check the Cookie information stored by the browser and automatic Login.
CookieFilter.java
package org.o7planning.simplewebapp.filter;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.o7planning.simplewebapp.beans.UserAccount;
import org.o7planning.simplewebapp.utils.DBUtils;
import org.o7planning.simplewebapp.utils.MyUtils;

@WebFilter(filterName = "cookieFilter", urlPatterns = { "/*" })
public class CookieFilter implements Filter {

   public CookieFilter() {
   }

   @Override
   public void init(FilterConfig fConfig) throws ServletException {

   }

   @Override
   public void destroy() {

   }

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
           throws IOException, ServletException {
       HttpServletRequest req = (HttpServletRequest) request;
       HttpSession session = req.getSession();

       UserAccount userInSession = MyUtils.getLoginedUser(session);
   
       if (userInSession != null) {
           session.setAttribute("COOKIE_CHECKED", "CHECKED");
           chain.doFilter(request, response);
           return;
       }

   
       // Connection was created in JDBCFilter.
       Connection conn = MyUtils.getStoredConnection(request);

 
       // Flag check cookie
       String checked = (String) session.getAttribute("COOKIE_CHECKED");
       if (checked == null && conn != null) {
           String userName = MyUtils.getUserNameInCookie(req);
           try {
               UserAccount user = DBUtils.findUser(conn, userName);
               MyUtils.storeLoginedUser(session, user);
           } catch (SQLException e) {
               e.printStackTrace();
           }
   
           // Mark checked.
           session.setAttribute("COOKIE_CHECKED", "CHECKED");
       }

       chain.doFilter(request, response);
   }

}

NOTE:

JDBCFilter & CookieFilter have the same  url-pattern =/*, you must be configured to ensure that JDBCFilter  is  executed first. Therefore, you need to declare the order in web.xml (There is no way to declare the order by Annotation).
<filter-mapping>
    <filter-name>jdbcFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>cookieFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
See full web.xml:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="http://java.sun.com/xml/ns/javaee"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                       http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
     id="WebApp_ID" version="3.0">
 <display-name>SimpleWebApp</display-name>


   <filter-mapping>
       <filter-name>jdbcFilter</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>
   
   <filter-mapping>
       <filter-name>cookieFilter</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>

 <welcome-file-list>

   <welcome-file>home</welcome-file>
   
   <welcome-file>index.html</welcome-file>
   
 </welcome-file-list>


</web-app>

15- Encoding Filter

EncodingFilter.java
package org.o7planning.simplewebapp.filter;

import java.io.IOException;
import java.sql.Connection;
import java.util.Collection;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

import org.o7planning.simplewebapp.conn.ConnectionUtils;
import org.o7planning.simplewebapp.utils.MyUtils;

@WebFilter(filterName = "encodingFilter", urlPatterns = { "/*" })
public class EncodingFilter implements Filter {

  public EncodingFilter() {
  }

  @Override
  public void init(FilterConfig fConfig) throws ServletException {

  }

  @Override
  public void destroy() {

  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          throws IOException, ServletException {
      request.setCharacterEncoding("UTF-8");

      chain.doFilter(request, response);
  }

}

16- Pages reuse

Some JSP pages will be used to embed into other JSP page at Runtime, through the use of:
<jsp:include page="_header.jsp"></jsp:include>
<jsp:include page="_menu.jsp"></jsp:include>

<jsp:include page="_footer.jsp"></jsp:include>
/WEB-INF/views/_header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<div style="background: #E0E0E0; height: 55px; padding: 5px;">
  <div style="float: left">
     <h1>My Site</h1>
  </div>

  <div style="float: right; padding: 10px; text-align: right;">

     <!-- User store in session with attribute: loginedUser -->
     Hello <b>${loginedUser.userName}</b>
   <br/>
     Search <input name="search">

  </div>

</div>
/WEB-INF/views/_menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
   pageEncoding="UTF-8"%>
   
<div style="padding: 5px;">

   <a href="${pageContext.request.contextPath}/">Home</a>
   |
   <a href="${pageContext.request.contextPath}/productList">Product List</a>
   |
   <a href="${pageContext.request.contextPath}/userInfo">My Account Info</a>
   |
   <a href="${pageContext.request.contextPath}/login">Login</a>
   
</div>  
/WEB-INF/views/_footer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
 
<div
  style="background: #E0E0E0; text-align: center; padding: 5px; margin-top: 10px;">
 
  @Copyright o7planning.org
 
</div>

17- Home Page

When entering the default path, eg enter the site's domain name it will display the home page (Case contextPath = ""), you need to declare your home page in <welcome-file-list> of web.xml
Link below is showing the content of the page index.html
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="http://java.sun.com/xml/ns/javaee"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                       http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
     id="WebApp_ID" version="3.0">
 <display-name>SimpleWebApp</display-name>


   <filter-mapping>
       <filter-name>jdbcFilter</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>
   
   <filter-mapping>
       <filter-name>cookieFilter</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>

 <welcome-file-list>

   <welcome-file>home</welcome-file>
   
   <welcome-file>index.html</welcome-file>
   
 </welcome-file-list>


</web-app>
Models of Home Page:
HomeServlet.java
package org.o7planning.simplewebapp.servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = { "/home"})
public class HomeServlet extends HttpServlet {
   private static final long serialVersionUID = 1L;

   public HomeServlet() {
       super();
   }

   @Override
   protected void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {

       
       // Forward to /WEB-INF/views/homeView.jsp
       // (Users can not access directly into JSP pages placed in WEB-INF)
       RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/WEB-INF/views/homeView.jsp");
       
       dispatcher.forward(request, response);
       
   }

   @Override
   protected void doPost(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {
       doGet(request, response);
   }

}
/WEB-INF/views/homeView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
  <head>
     <meta charset="UTF-8">
     <title>Home Page</title>
  </head>
  <body>

     <jsp:include page="_header.jsp"></jsp:include>
     <jsp:include page="_menu.jsp"></jsp:include>
   
      <h3>Home Page</h3>
     
      This is demo Simple web application using jsp,servlet &amp; Jdbc. <br><br>
      <b>It includes the following functions:</b>
      <ul>
         <li>Login</li>
         <li>Storing user information in cookies</li>
         <li>Product List</li>
         <li>Create Product</li>
         <li>Edit Product</li>
         <li>Delete Product</li>
      </ul>

     <jsp:include page="_footer.jsp"></jsp:include>

  </body>
</html>
Rerun your application, and try two URLs:

NOTE:  For whatever reason, the link http: //localhost:8080/SimpleWebApp/ is still displayed content of index.html, you can delete or rename the  index.html file, for example, you can change it into _index.html

18- Login Page - LoginServlet

This is a model of  Login function:
LoginServlet.java
package org.o7planning.simplewebapp.servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = { "/login"})
public class LoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public LoginServlet() {
        super();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        
        // Forward to /WEB-INF/views/loginView.jsp
        // (Users can not access directly into JSP pages placed in WEB-INF)        
        RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/WEB-INF/views/loginView.jsp");
        
        dispatcher.forward(request, response);
        
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
DoLoginServlet.java
package org.o7planning.simplewebapp.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.o7planning.simplewebapp.beans.UserAccount;
import org.o7planning.simplewebapp.utils.DBUtils;
import org.o7planning.simplewebapp.utils.MyUtils;

@WebServlet(urlPatterns = { "/doLogin" })
public class DoLoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public DoLoginServlet() {
        super();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String userName = request.getParameter("userName");
        String password = request.getParameter("password");
        String rememberMeStr = request.getParameter("rememberMe");
        boolean remember= "Y".equals(rememberMeStr);

        
        UserAccount user = null;
        boolean hasError = false;
        String errorString = null;

        if (userName == null || password == null
                 || userName.length() == 0 || password.length() == 0) {
            hasError = true;
            errorString = "Required username and password!";
        } else {
            Connection conn = MyUtils.getStoredConnection(request);
            try {
             
                user = DBUtils.findUser(conn, userName, password);
                
                if (user == null) {
                    hasError = true;
                    errorString = "User Name or password invalid";
                }
            } catch (SQLException e) {
                e.printStackTrace();
                hasError = true;
                errorString = e.getMessage();
            }
        }
       
        // If error, forward to /WEB-INF/views/login.jsp
        if (hasError) {
            user = new UserAccount();
            user.setUserName(userName);
            user.setPassword(password);
            
       
            // Store information in request attribute, before forward.
            request.setAttribute("errorString", errorString);
            request.setAttribute("user", user);

      
            // Forward to /WEB-INF/views/login.jsp
            RequestDispatcher dispatcher //
            = this.getServletContext().getRequestDispatcher("/WEB-INF/views/loginView.jsp");

            dispatcher.forward(request, response);
        }
    
        // If no error
        // Store user information in Session
        // And redirect to userInfo page.
        else {
            HttpSession session = request.getSession();
            MyUtils.storeLoginedUser(session, user);
            
             // If user checked "Remember me".
            if(remember)  {
                MyUtils.storeUserCookie(response,user);
            }
   
            // Else delete cookie.
            else  {
                MyUtils.deleteUserCookie(response);
            }                       
     
            // Redirect to userInfo page.
            response.sendRedirect(request.getContextPath() + "/userInfo");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
UserInfoServlet.java
package org.o7planning.simplewebapp.servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.o7planning.simplewebapp.beans.UserAccount;
import org.o7planning.simplewebapp.utils.MyUtils;

@WebServlet(urlPatterns = { "/userInfo" })
public class UserInfoServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public UserInfoServlet() {
        super();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();


        // Check User has logged on
        UserAccount loginedUser = MyUtils.getLoginedUser(session);

 
        // Not logged in
        if (loginedUser == null) {
      
            // Redirect to login page.
            response.sendRedirect(request.getContextPath() + "/login");
            return;
        }
 
        // Store info in request attribute
        request.setAttribute("user", loginedUser);

 
        // Logined, forward to /WEB-INF/views/userInfoView.jsp
        RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/WEB-INF/views/userInfoView.jsp");
        dispatcher.forward(request, response);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
/WEB-INF/views/loginView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
 <head>
    <meta charset="UTF-8">
    <title>Login</title>
 </head>
 <body>

    <jsp:include page="_header.jsp"></jsp:include>
    <jsp:include page="_menu.jsp"></jsp:include>

    <h3>Login Page</h3>

    <p style="color: red;">${errorString}</p>

    <form method="POST" action="doLogin">
       <table border="0">
          <tr>
             <td>User Name</td>
             <td><input type="text" name="userName" value= "${user.userName}" /> </td>
          </tr>
          <tr>
             <td>Password</td>
             <td><input type="text" name="password" value= "${user.password}" /> </td>
          </tr>
          <tr>
             <td>Remember me</td>
             <td><input type="checkbox" name="rememberMe" value= "Y" /> </td>
          </tr>
          <tr>
             <td colspan ="2">
                <input type="submit" value= "Submit" />
                <a href="${pageContext.request.contextPath}/">Cancel</a>
             </td>
          </tr>
       </table>
    </form>

    <p style="color:blue;">User Name: tom, password: tom001 or jerry/jerry001</p>

    <jsp:include page="_footer.jsp"></jsp:include>

 </body>
</html>
/WEB-INF/views/userInfoView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
 <head>
    <meta charset="UTF-8">
    <title>User Info</title>
 </head>
 <body>

    <jsp:include page="_header.jsp"></jsp:include>
    <jsp:include page="_menu.jsp"></jsp:include>

    <h3>Hello: ${user.userName}</h3>

    User Name: <b>${user.userName}</b>
    <br />
    Gender: ${user.gender } <br />

    <jsp:include page="_footer.jsp"></jsp:include>

 </body>
</html>
Running your application:

19- Product List Page

Model:
ProductListServlet.java
package org.o7planning.simplewebapp.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.o7planning.simplewebapp.beans.Product;
import org.o7planning.simplewebapp.utils.DBUtils;
import org.o7planning.simplewebapp.utils.MyUtils;

@WebServlet(urlPatterns = { "/productList" })
public class ProductListServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public ProductListServlet() {
        super();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Connection conn = MyUtils.getStoredConnection(request);

        String errorString = null;
        List<Product> list = null;
        try {
            list = DBUtils.queryProduct(conn);
        } catch (SQLException e) {
            e.printStackTrace();
            errorString = e.getMessage();
        }
  
        // Store info in request attribute, before forward to views
        request.setAttribute("errorString", errorString);
        request.setAttribute("productList", list);
        
    
        // Forward to /WEB-INF/views/productListView.jsp
        RequestDispatcher dispatcher = request.getServletContext()
                .getRequestDispatcher("/WEB-INF/views/productListView.jsp");
        dispatcher.forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
/WEB-INF/views/productListView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
<!DOCTYPE html>
<html>
 <head>
    <meta charset="UTF-8">
    <title>Product List</title>
 </head>
 <body>

    <jsp:include page="_header.jsp"></jsp:include>
    <jsp:include page="_menu.jsp"></jsp:include>

    <h3>Product List</h3>

    <p style="color: red;">${errorString}</p>

    <table border="1" cellpadding="5" cellspacing="1" >
       <tr>
          <th>Code</th>
          <th>Name</th>
          <th>Price</th>
          <th>Edit</th>
          <th>Delete</th>
       </tr>
       <c:forEach items="${productList}" var="product" >
          <tr>
             <td>${product.code}</td>
             <td>${product.name}</td>
             <td>${product.price}</td>
             <td>
                <a href="editProduct?code=${product.code}">Edit</a>
             </td>
             <td>
                <a href="deleteProduct?code=${product.code}">Delete</a>
             </td>
          </tr>
       </c:forEach>
    </table>

    <a href="createProduct" >Create Product</a>

    <jsp:include page="_footer.jsp"></jsp:include>

 </body>
</html>
Rerun Application:

20- Add Product Page

Model:
CreateProductServlet.java
package org.o7planning.simplewebapp.servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = { "/createProduct" })
public class CreateProductServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;

  public CreateProductServlet() {
      super();
  }

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {

      RequestDispatcher dispatcher = request.getServletContext()
              .getRequestDispatcher("/WEB-INF/views/createProductView.jsp");
      dispatcher.forward(request, response);

  }

  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
      doGet(request, response);
  }

}
DoCreateProductServlet.java
package org.o7planning.simplewebapp.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.o7planning.simplewebapp.beans.Product;
import org.o7planning.simplewebapp.utils.DBUtils;
import org.o7planning.simplewebapp.utils.MyUtils;

@WebServlet(urlPatterns = { "/doCreateProduct" })
public class DoCreateProductServlet extends HttpServlet {
   private static final long serialVersionUID = 1L;

   public DoCreateProductServlet() {
       super();
   }

   @Override
   protected void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {
       Connection conn = MyUtils.getStoredConnection(request);

       String code = (String) request.getParameter("code");
       String name = (String) request.getParameter("name");
       String priceStr = (String) request.getParameter("price");
       float price = 0;
       try {
           price = Float.parseFloat(priceStr);
       } catch (Exception e) {
       }
       Product product = new Product(code, name, price);

       String errorString = null;

     
       // Product ID is the string literal [a-zA-Z_0-9]
       // with at least 1 character
       String regex = "\\w+";

       if (code == null || !code.matches(regex)) {
           errorString = "Product Code invalid!";
       }

       if (errorString == null) {
           try {
               DBUtils.insertProduct(conn, product);
           } catch (SQLException e) {
               e.printStackTrace();
               errorString = e.getMessage();
           }
       }
       
       // Store infomation to request attribute, before forward to views.
       request.setAttribute("errorString", errorString);
       request.setAttribute("product", product);

       // If error, forward to Edit page.
       if (errorString != null) {
           RequestDispatcher dispatcher = request.getServletContext()
                   .getRequestDispatcher("/WEB-INF/views/createProductView.jsp");
           dispatcher.forward(request, response);
       }

       // If everything nice.
       // Redirect to the product listing page.            
       else {
           response.sendRedirect(request.getContextPath() + "/productList");
       }

   }

   @Override
   protected void doPost(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {
       doGet(request, response);
   }

}
/WEB-INF/views/createProductView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE html>
<html>
 <head>
    <meta charset="UTF-8">
    <title>Create Product</title>
 </head>
 <body>

    <jsp:include page="_header.jsp"></jsp:include>
    <jsp:include page="_menu.jsp"></jsp:include>
   
    <h3>Create Product</h3>
   
    <p style="color: red;">${errorString}</p>
   
    <form method="POST" action="doCreateProduct">
       <table border="0">
          <tr>
             <td>Code</td>
             <td><input type="text" name="code" value="${product.code}" /></td>
          </tr>
          <tr>
             <td>Name</td>
             <td><input type="text" name="name" value="${product.name}" /></td>
          </tr>
          <tr>
             <td>Price</td>
             <td><input type="text" name="price" value="${product.price}" /></td>
          </tr>
          <tr>
             <td colspan="2">                  
                 <input type="submit" value="Submit" />
                 <a href="productList">Cancel</a>
             </td>
          </tr>
       </table>
    </form>
   
    <jsp:include page="_footer.jsp"></jsp:include>
   
 </body>
</html>

21- Edit Product Page

Model:
EditProductServlet.java
package org.o7planning.simplewebapp.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.o7planning.simplewebapp.beans.Product;
import org.o7planning.simplewebapp.utils.DBUtils;
import org.o7planning.simplewebapp.utils.MyUtils;

@WebServlet(urlPatterns = { "/editProduct" })
public class EditProductServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public EditProductServlet() {
        super();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Connection conn = MyUtils.getStoredConnection(request);

        String code = (String) request.getParameter("code");

        Product product = null;

        String errorString = null;

        try {
            product = DBUtils.findProduct(conn, code);
        } catch (SQLException e) {
            e.printStackTrace();
            errorString = e.getMessage();
        }

        
        // If no error.
        // The product does not exist to edit.
        // Redirect to productList page.
        if (errorString != null && product == null) {
            response.sendRedirect(request.getServletPath() + "/productList");
            return;
        }

        // Store errorString in request attribute, before forward to views.
        request.setAttribute("errorString", errorString);
        request.setAttribute("product", product);

        RequestDispatcher dispatcher = request.getServletContext()
                .getRequestDispatcher("/WEB-INF/views/editProductView.jsp");
        dispatcher.forward(request, response);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
DoEditProductServlet.java
package org.o7planning.simplewebapp.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.o7planning.simplewebapp.beans.Product;
import org.o7planning.simplewebapp.utils.DBUtils;
import org.o7planning.simplewebapp.utils.MyUtils;

@WebServlet(urlPatterns = { "/doEditProduct" })
public class DoEditProductServlet extends HttpServlet {
   private static final long serialVersionUID = 1L;

   public DoEditProductServlet() {
       super();
   }

   @Override
   protected void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {
       Connection conn = MyUtils.getStoredConnection(request);

       String code = (String) request.getParameter("code");
       String name = (String) request.getParameter("name");
       String priceStr = (String) request.getParameter("price");
       float price = 0;
       try {
           price = Float.parseFloat(priceStr);
       } catch (Exception e) {
       }
       Product product = new Product(code, name, price);

       String errorString = null;

       try {
           DBUtils.updateProduct(conn, product);
       } catch (SQLException e) {
           e.printStackTrace();
           errorString = e.getMessage();
       }

       // Store infomation to request attribute, before forward to views.
       request.setAttribute("errorString", errorString);
       request.setAttribute("product", product);


       // If error, forward to Edit page.
       if (errorString != null) {
           RequestDispatcher dispatcher = request.getServletContext()
                   .getRequestDispatcher("/WEB-INF/views/editProductView.jsp");
           dispatcher.forward(request, response);
       }
       
       // If everything nice.
       // Redirect to the product listing page.            
       else {
           response.sendRedirect(request.getContextPath() + "/productList");
       }

   }

   @Override
   protected void doPost(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {
       doGet(request, response);
   }

}
/WEB-INF/views/editProductView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
 <head>
    <meta charset="UTF-8">
    <title>Edit Product</title>
 </head>
 <body>

    <jsp:include page="_header.jsp"></jsp:include>
    <jsp:include page="_menu.jsp"></jsp:include>

    <h3>Edit Product</h3>

    <p style="color: red;">${errorString}</p>

    <c:if test="${not empty product}">
       <form method="POST" action="doEditProduct">
          <input type="hidden" name="code" value="${product.code}" />
          <table border="0">
             <tr>
                <td>Code</td>
                <td style="color:red;">${product.code}</td>
             </tr>
             <tr>
                <td>Name</td>
                <td><input type="text" name="name" value="${product.name}" /></td>
             </tr>
             <tr>
                <td>Price</td>
                <td><input type="text" name="price" value="${product.price}" /></td>
             </tr>
             <tr>
                <td colspan = "2">
                    <input type="submit" value="Submit" />
                    <a href="${pageContext.request.contextPath}/productList">Cancel</a>
                </td>
             </tr>
          </table>
       </form>
    </c:if>

    <jsp:include page="_footer.jsp"></jsp:include>

 </body>
</html>

22- Delete Product

Model:
DeleteProductServlet.java
package org.o7planning.simplewebapp.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.o7planning.simplewebapp.utils.DBUtils;
import org.o7planning.simplewebapp.utils.MyUtils;

@WebServlet(urlPatterns = { "/deleteProduct" })
public class DeleteProductServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public DeleteProductServlet() {
        super();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Connection conn = MyUtils.getStoredConnection(request);

        String code = (String) request.getParameter("code");

        String errorString = null;

        try {
            DBUtils.deleteProduct(conn, code);
        } catch (SQLException e) {
            e.printStackTrace();
            errorString = e.getMessage();
        }
        

        // If an error redirected to an error page.
        if (errorString != null) {

            // Store the information in the request attribute, before forward to views.
            request.setAttribute("errorString", errorString);
            //
            RequestDispatcher dispatcher = request.getServletContext()
                    .getRequestDispatcher("/WEB-INF/views/deleteProductErrorView.jsp");
            dispatcher.forward(request, response);
        }

        // If everything nice.
        // Redirect to the product listing page.        
        else {
            response.sendRedirect(request.getContextPath() + "/productList");
        }

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
/WEB-INF/views/deleteProductErrorView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
 <head>
    <meta charset="UTF-8">
    <title>Delete Product</title>
 </head>

 <body>

    <jsp:include page="_header.jsp"></jsp:include>
    <jsp:include page="_menu.jsp"></jsp:include>
   
    <h3>Delete Product</h3>
   
    <p style="color: red;">${errorString}</p>
    <a href="productList">Product List</a>
   
    <jsp:include page="_footer.jsp"></jsp:include>
   
 </body>
</html>