How to work with Servlet, JSP and JDBC?

  1. A servlet is a Java class that can be loaded dynamically into and run by special web server called the servlet container — most popular one is Tomcat.
  2. Servlets interact with clients via request-response model based on HTTP (HTTPS also supported).
  3. A servlet can serve static content such as HTML pages and images file, but it would be faster if those contents are served by a HTTP server such as Apache web server or Microsoft Internet Information Server.
  4. A servlet is loaded by servlet container the first time it is requested. The servlet then is forward the user request, process it and returns the response to the servlet container which then sends the response back to user.
  5. Using Deployment Descriptor (web.xml), the servlet container will know which servlet to call upon receiving a request from client. Alternatively on servlet 3.0 onwards, we can use annotations such as @WebServlet(“/abc.html”) to map servlets.

Setup Eclipse IDE for Java EE

  1. Download Eclipse from this link — https://www.eclipse.org/downloads/packages/release/mars/r/eclipse-ide-java-ee-developers
  2. Extract the downloaded item to your computer. In the folder, launch eclipse application (no installation needed).
  3. When the application successfully launches, make sure you’re in the Java EE perspective. You can switch to this perspective by click “Open Perspective” icon located on the top right and select “Java EE”.

Download Tomcat and add to Eclipse

  1. Go to this link and it will show you which Tomcat version you should be interested to work with — https://tomcat.apache.org/whichversion.html
  2. Download the interested Tomcat version and extract to your computer.
  3. Go back to Eclipse. At the “Server” tab in the bottom pane, click the link to add a new server. Select the Tomcat version that you have downloaded previously. At “Server runtime environment”, click add and paste the path containing the extracted Tomcat version folder. Click finish.
  4. Right click on your added Tomcat server and click start. The server should start successfully.
  5. You can configure your Tomcat server for example HTTP/1.1 port number by double clicking the Tomcat server to bring up the overview window.

Start creating web project

  1. Right click at Project Explorer and create new “Dynamic Web Project”. Enter project name and click finish.
  2. Right click at your project in the Project Explorer and create new HTML file of name index.html in default location of WebContent.
  3. In the index.html, let’s create a login form within the body tag to takes in username and password and simply display the username upon form submit.
<!DOCTYPE html>
<html>
<body>
 <form action=login method="post">
  Please enter username and password:<br>
  Username: <input type="text" name="username"><br>
  Password <input type="text" name="password"><br>
  <input type="submit">
 </form>
</body>
</html>

4. Run the program by right clicking at the your project name and select “Run As” and “Run on Server”. In this step, the first page will be the index.html.

5. However if you click run button and your active window is on another page (for example, page2.html) then it will be shown in the browser instead of the index.html. For the next following examples, we will be run our application at our LoginServlet.java.

6. Inside /Java Resources/src, let’s create a java class called LoginServlet. This class will extends HttpServlet class. Since we are running our application directly from LoginServlet (meaning we are not using index.html), we need to build our form inside our servlet. For this, we will create a method to show our login form.

public void showLoginForm(HttpServletRequest req, HttpServletResponse res) throws IOException {
  res.setContentType("text/html");
  PrintWriter out = res.getWriter();
  out.println("<html>");
  out.println("<head>");
  out.println("<title>Login</title>");
  out.println("</head>");
  out.println("<body>");
  out.println("<br>Please enter username and password");
  out.println("<form method=post>");
  out.println("<br>Username: <input type=text name=username>");
  out.println("<br>Password: <input type=text name=password>");
  out.println("<br><input type=submit>");
  out.println("</form>");
  out.println("</body>");
  out.println("</html>");
 }

HTTP methods — doGet and doPost

  1. Let’s extend our LoginServlet class to HttpServlet. This extension allows us to use the method doGet and doPost. Get and Post are common methods of the HTTP to indicate the kind of action that we want. Here are definition of some of the methods commonly used:
  • DELETE — Removes specified resource
  • GET — Fetches data from server
  • POST — Sends data to server
  • PUT — Replaces current representation of target resource with uploaded content

2. Since we want to display our form to the client browser is equivalent to GET method, we should show our form in the doGet method. When the user clicks submit, is equivalent to POST method in which we send data back to server. Hence in the doPost method, we retrieve the data using getParameter method.

package com.davidcheah;
import java.io.IOException;
import java.io.PrintWriter;
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("/login")
public class LoginServlet extends HttpServlet {
public void showLoginForm(HttpServletRequest req, HttpServletResponse res) throws IOException {
  res.setContentType("text/html");
  PrintWriter out = res.getWriter();
  out.println("<html>");
  out.println("<head>");
  out.println("<title>Login</title>");
  out.println("</head>");
  out.println("<body>");
  out.println("<br>Please enter username and password");
  out.println("<form method=post>");
  out.println("<br>Username: <input type=text name=username>");
  out.println("<br>Password: <input type=text name=password>");
  out.println("<br><input type=submit>");
  out.println("</form>");
  out.println("</body>");
  out.println("</html>");
 }

 public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
  showLoginForm(req, res);
 }

 public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
  String username = req.getParameter("username");
  String password = req.getParameter("password");
  if (username.isEmpty() || password.isEmpty()) {
   showLoginForm(req, res);
  } else {
   out.println("Hello: " + username);
  }

 }
}

Deployment Description (web.xml)

  1. In the index.html form, when we click on submit button and ask for /login path, we really want to call LoginServlet but our application does not know to do that. Hence we need to link both via deployment description of web.xml.

2. In the web.xml, for every servlet we need to add 2 tags (servlet and servlet-mapping) with 2 sub-tags each:

<?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_3_1.xsd" id="WebApp_ID" version="3.1">
<servlet>
 <servlet-name>servlet1</servlet-name>
 <servlet-class>com.davidcheah.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
 <servlet-name>servlet1</servlet-name>
 <url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>

3. The 2 tags, <servlet> and <servlet-mapping> are bound to each other by a common sub-tag <servlet-name> which can be any name. Hence whenever a /login path is requested, from the web.xml it will be able to retrieve to correct servlet class which is LoginServlet (notice you have to provide package name with class name) from the common servlet name tag.

4. Restart the server and you should see the application working.

Web Annotation

  1. Another way to link servlet class to url is to use web annotation. In the LoginServlet class, just before the class name, add the following: @WebServlet("/login")

Request Dispatcher

  1. Let’s create the second servlet that will display welcome message to user.
  2. Don’t forget to create the 2 tags in web.xml for every new servlet created.
<servlet>
    <servlet-name>servlet2</servlet-name>
    <servlet-class>com.davidcheah.WelcomeServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>servlet2</servlet-name>
    <url-pattern>/welcome</url-pattern>
  </servlet-mapping>

3. In the LoginServlet class, we can call another servlet using RequestDispatcher or redirection method. Using the RequestDispatcher method, we can pass information to request to be retrieve by second servlet using setAttribute method. Finally we use forward to pass the request and response to second servlet

package com.davidcheah;
import java.io.IOException;
import java.io.PrintWriter;
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("/login")
public class LoginServlet extends HttpServlet {
public void showLoginForm(HttpServletRequest req, HttpServletResponse res) throws IOException {
  res.setContentType("text/html");
  PrintWriter out = res.getWriter();
  out.println("<html>");
  out.println("<head>");
  out.println("<title>Login</title>");
  out.println("</head>");
  out.println("<body>");
  out.println("<br>Please enter username and password");
  out.println("<form method=post>");
  out.println("<br>Username: <input type=text name=username>");
  out.println("<br>Password: <input type=text name=password>");
  out.println("<br><input type=submit>");
  out.println("</form>");
  out.println("</body>");
  out.println("</html>");
 }

 public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
  showLoginForm(req, res);
 }

 public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
  String username = req.getParameter("username");
  String password = req.getParameter("password");
  if (username.isEmpty() || password.isEmpty()) {
   showLoginForm(req, res);
  } else {
RequestDispatcher rd = req.getRequestDispatcher("welcome");
   req.setAttribute("username", username);
   rd.forward(req, res);
  }

 }
}

4. In the WelcomeServlet, we can retrieve the data passed from previous servlet using getAttribute method. The attribute is type Object , hence we need to have a proper casting. Notice in after request has been dispatched to WelcomeServlet, the url is showing login.

package com.davidcheah;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class WelcomeServlet extends HttpServlet{

 public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException {
  String username = (String) req.getAttribute("username");

  PrintWriter out = res.getWriter();
  out.println("Hello: " + username);
 }
}

Send Redirect

  1. So let’s recap, a servlet can call another servlet using forward without responding back to client. sendRedirect involves servlet responding back to client and asking to go to another url that leads to second servlet. Meaning there is a round trip back to the client.
  2. Using sendRedirect , you can pass information between first servlet to next request by appending query the destination url and using req.getParameter to retrieve it in the second servlet.
  3. LoginServlet
package com.davidcheah;
import java.io.IOException;
import java.io.PrintWriter;
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("/login")
public class LoginServlet extends HttpServlet {
public void showLoginForm(HttpServletRequest req, HttpServletResponse res) throws IOException {
  res.setContentType("text/html");
  PrintWriter out = res.getWriter();
  out.println("<html>");
  out.println("<head>");
  out.println("<title>Login</title>");
  out.println("</head>");
  out.println("<body>");
  out.println("<br>Please enter username and password");
  out.println("<form method=post>");
  out.println("<br>Username: <input type=text name=username>");
  out.println("<br>Password: <input type=text name=password>");
  out.println("<br><input type=submit>");
  out.println("</form>");
  out.println("</body>");
  out.println("</html>");
 }

 public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
  showLoginForm(req, res);
 }

 public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
  String username = req.getParameter("username");
  String password = req.getParameter("password");
  if (username.isEmpty() || password.isEmpty()) {
   showLoginForm(req, res);
  } else {
   res.sendRedirect("welcome?user=" + username);
  }

 }
}

4. Since we are passing parameter via url, we need to use doGet to retrieve the information via req.getParameter .

package com.davidcheah;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class WelcomeServlet extends HttpServlet{

 public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {

  String username = req.getParameter("username");

  PrintWriter out = res.getWriter();
  out.println("Hello " + username);
 }
}

RequestDispatcher VS sendRedirect Recap

  1. RequestDispatcher forwards request to another page without going back to client browser whereas sendRedirect goes back to client browser before requesting new url.
  2. Use req.setAttribute to pass data using RequestDispatcher and url rewriting usingsendRedirect .

What is JSP?

  1. We can see to build a form in Server, we have to wrap each line of the HTML with PrinterWriter and it can be quite a hassle. We can further improve this by using JSP.
  2. JSP which stands for Java Server Pages is an extension of the servlet technology created to support authoring of HTML and XML pages. In MVC model, JSP can be use to represent the view while Servlet is the controller. In JSP, most of the building blocks are in HTML but you can insert Java code blocks whereas for Servlet it is build entirely using Java.
  3. Let’s create a WelcomePage.jsp to mimic WelcomeServlet.java.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="blue">
 <%
  String username = request.getParameter("user");
  out.println("Hello user: " + username);
 %>
</body>
</html>

4. Back in our LoginServlet.java. We can call our new jsp page using request dispatch or redirection.

public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
  String username = req.getParameter("username");
  String password = req.getParameter("password");
  if (username.isEmpty() || password.isEmpty()) {
   showLoginForm(req, res);
  } else {
   res.sendRedirect("WelcomePage.jsp?user="+username);
  }

 }

5. Let us also extract our login form into a separate jsp file call LoginPage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login JSP Page</title>
</head>
<body>
<form action=login method="post">
  Please enter username and password:<br>
  Username: <input type="text" name="username"><br>
  Password <input type="text" name="password"><br>
  <input type="submit">
 </form>
</body>
</html>

6. Previously, we run our application on LoginServlet.java. Since now we have LoginPage.jsp, we can add this as our startup page. To do this, go to web.xml and add the following lines within tag <web-app> . Now, when we run our application at project level, the first startup page will be LoginPage.jsp.

<welcome-file-list>  
    <welcome-file>LoginPage.jsp</welcome-file>  
</welcome-file-list>

7. Since we have extracted our login form, we need to remove method showLoginForm in LoginServlet and redirect user to LoginPage.jsp if there is a login failure. Method doGet can be removed in the servlet since have delegate form display to jsp file.

package com.davidcheah;
import java.io.IOException;
import java.io.PrintWriter;
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("/login")
public class LoginServlet extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
  String username = req.getParameter("username");
  String password = req.getParameter("password");
  if (username.isEmpty() || password.isEmpty()) {
   res.sendRedirect("LoginPage.jsp?");
  } else {
   res.sendRedirect("WelcomePage.jsp?user="+username);
  }

 }
}

Servlet Life Cycle

  1. Let’s talk abit about life cycle of servlet. There are 3 lifecycles; init, service and destroy. For each life cycle, there is a dedicated method that will be triggered when servlet goes to specific life cycle.
  2. The init method is called when the servlet class has been instantiated. You can overwrite this method to write initialization code that needs to run only once, such as loading database driver, initialize value and so on.
  3. The service method is called whenever servlet needs to respond to a request.
  4. The destroy method is called before servlet container removes the servlet instance from service.

JDBC

  1. JDBC stands for Java Database Connectivity. It is an API that allows to connect and execute query to a database.
  2. Before using the API, we must download the JDBC driver. For this example, we will be using MySQL as our database.
  3. Download and extact the jar file from the link — https://dev.mysql.com/downloads/connector/j/
  4. Copy the jar file and paste it inside Project Name/WebContent/WEB-INF/lib at project explorer window. (I am using mysql-connector-java-5.1.47)
  5. Let’s add an init method inside our LoginServlet to allow us to load our JDBC database driver. Do take note, on version 5.1 onwards, class name has been changed to com.mysql.cj.jdbc.Driver .
public void init() {
  // 1. Load JDBC driver
  try {
   Class.forName("com.mysql.cj.jdbc.Driver");
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  }
 }

6. Before we make a connection to our database, we need to of course create a database. At our MySQL Workbench, we create a new database call demowebappdb and select it.

CREATE DATABASE demowebappdb
USE demowebappdb

7. Next, we need to create a new table call users to keep our username and password.

CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(255), password VARCHAR(255))
INSERT INTO users (username, password) VALUES ('john', 'john123')

8. Back to our eclipse, let’s create method call login that will return a boolean TRUE if there is a user in our database with the login name and password. We have loaded our JDBC driver in init method, hence the following steps involve creating a connection, a statement, execute our query and store the response in ResultSet.

9. We need to connect to our database url with database username and password. The format for mysql is “jdbc:mysql://localhost:” + port number (default=3306) + “/” + your database name.

10. Here is our login method. Notice the rs.next() is because the cursor is initially is before the first position. Hence we need to shift a row down to obtain the first result.

public boolean login(String name, String password) {
  String url = "jdbc:mysql://localhost:3306/demowebappdb";
  String dbUsername = "root";
  String dbPassword = "password";
  String query = "select id from users where username='" + name + "' and password='" + password + "'";
try {

  // 2. Create a connection
Connection con = DriverManager.getConnection(url, dbUsername, dbPassword);

  // 3. Create a statement
Statement st = con.createStatement();

  // 4. Create a ResultSet
ResultSet rs = st.executeQuery(query);

  if (rs.next()) {
   // 5. Close all connections
   rs.close();
   st.close();
   con.close();
   return true;
  }

  // 5. Close all connections
  rs.close();
  st.close();
  con.close();
  return false;
 }
 catch (SQLException e) {
  System.out.println(e.toString());
 } catch (Exception e) {
  System.out.println(e.toString());
 }
 return false;
}

And we are done~

Github

Source code available here: https://github.com/tattwei46/DemoWebAppJava

About the author

Founder of tattweicheah.com. Loves music, sport and most importantly software development.

Leave a Reply

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