JAKARTA EE FOR JUNIOR DEVELOPERS - Lesson 5 Using JSP and Servlet to save data in the database (Part 1)

 


INTRODUCTION

In this Jakarta EE for Junior Developers lesson, we will see how we can save data to the database using a combination of JSP and Servlet. We will cover as much theory as needed to be able to execute the simple process of a transaction. Once we complete this small web application, we will return to the theory of Jakarta EE Persistence to analyze more theory and practical scenarios.

FEW WORDS ABOUT THE HTTP PROTOCOL

The HTTP (HyperText Transfer Protocol) is a protocol used for transferring data over the web. It’s the foundation of any data exchange on the Web and is used for accessing websites, retrieving web pages, and transmitting data between web clients (like browsers) and web servers.

HTTP operates on a client-server model. The client (like a browser) sends an HTTP request to the server (in our case Wildfly), which processes the request and sends back an HTTP response with the requested data or an error message.

HTTP is stateless, meaning that each request is independent and does not retain any information about previous requests. The server doesn’t store information about past interactions. If stateful behavior is needed (such as keeping track of a user’s session), technologies like cookies or sessions are used to maintain state between requests.

HTTP defines several request methods (also known as HTTP verbs) to specify the desired action. Common methods include:

  • GET: Retrieve data from the server.
  • POST: Send data to the server to create or update a resource.
  • PUT: Update a resource on the server.
  • DELETE: Remove a resource from the server.
  • PATCH: Partially update a resource.

WHAT IS A SERVLET

According to Jakarta EE Servlet Specification (https://jakarta.ee/specifications/servlet/6.0/jakarta-servlet-spec-6.0#what-is-a-servlet), a Servlet is a Java class that responds to HTTP requests in a web-based application. The Servlet API defines how these classes interact with clients and servers. Essentially, servlets are server-side components responsible for handling requests from a client (usually a web browser), processing that request (which could involve complex logic or interacting with databases), and then generating an appropriate HTTP response.

Servlets in Jakarta EE receive HTTP requests (GET, POST, PUT, DELETE, etc.), process them, and generate an appropriate HTTP response.

Servlets run in a Servlet Container (also known as a Web Container). The servlet container is a part of a Web Server or Application Server that interacts with the servlet and the client, handling the request-response cycle.

The servlet container provides the environment necessary to execute servlets, managing their lifecycle, handling incoming requests, and sending responses. It also provides services like session management, security, and connection pooling.


CREATING OUR FIRST SERVLET

To begin with, let's create a new package named com.mycompany.controllers.



Now we right click on the package and we select to create a Servlet.


Give the name Controller to the Servlet and click on the Next button.


You do not have to click on the "Add information to deployment descriptor (web.xml)" checkbox. 

In Jakarta EE, servlets can be configured in two ways:
  • Using annotations: You can annotate a servlet class with @WebServlet to configure it in your application.
  • Using web.xml (deployment descriptor): Alternatively, you can define the servlet and its mapping in the web.xml file.
We will follow the second way so leave the checkbox unchecked. Click Finish to complete the creation of the Servlet.




Before we explain what we have created, let's clean up the extra code we do not need. A clean version of the Servlet should be as follows:

Controller.java

package com.mycompany.controllers;

import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet(name = "Controller", urlPatterns = {"/Controller"})
public class Controller extends HttpServlet {

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

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

}

CODE EXPLANATION

@WebServlet(name = "Controller", urlPatterns = {"/Controller"})

According to Jakarta EE Servlet Specification (Section 8.1.1 @WebServlet), the @WebServlet annotation is used to define a servlet in Java. A servlet is a Java class that handles HTTP requests and responses, usually as part of a web application running on a server. The annotation tells the web container (Wildfly in our case) that the class is a servlet and should be registered and available to handle HTTP requests.
  • name = "Controller": This defines the name of the servlet. The name is typically used for internal identification, and it could be referenced in configuration files or other places. In this case, the servlet is named "Controller."
  • urlPatterns = {"/Controller"}: This specifies the URL pattern(s) that this servlet will handle. In this case, the servlet will be invoked when a request is made to the URL path /Controller. So, if someone accesses http://yourdomain.com/Controller, this servlet will handle that request.

public class Controller extends HttpServlet

public class Controller: This defines the class Controller that will handle HTTP requests for the /Controller URL.

extends HttpServlet: The class extends the HttpServlet class, which is part of the Java Servlet API. The HttpServlet class provides methods like doGet(), doPost(), etc., that you can override to handle HTTP GET, POST, PUT, and DELETE requests.

By extending HttpServlet, the Controller class inherits functionality to handle HTTP requests. You can override methods like doGet() to process GET requests or doPost() to process POST requests.

doPost(HttpServletRequest request,
            HttpServletResponse response)

The doPost method is part of the HttpServlet class and is used to handle HTTP POST requests in a servlet.

HttpServletRequest request: This object represents the request that was made by the client. It contains all the information about the incoming request, such as:

  • Form parameters (sent by the client in the body of the POST request).
  • HTTP headers.
  • Cookies.
  • Request attributes.
  • And other details like the method (POST), URI, etc.

For example, if a user submits a form, the form data will be available in the request object.

HttpServletResponse response: This object represents the response that will be sent to the client. You use it to modify the response, such as setting the content type, writing content to the response body, or redirecting the user to another URL.

As you remember, we have created an entity class named Employee. This class has been converted to a table in our database. So now we need to fill each of the columns of the table with some data received from a client. The Servlet will be responsible for receiving the values, convert them to an object type of an employee and save it to the database. Let's see first the complete code and then we will explain it.

package com.mycompany.controllers;

import com.mycompany.jakartaee.entities.Employee;
import jakarta.annotation.Resource;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.transaction.HeuristicMixedException;
import jakarta.transaction.HeuristicRollbackException;
import jakarta.transaction.NotSupportedException;
import jakarta.transaction.RollbackException;
import jakarta.transaction.SystemException;
import jakarta.transaction.UserTransaction;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

@WebServlet(name = "Controller", urlPatterns = {"/Controller"})
public class Controller extends HttpServlet {
   
    @PersistenceContext
    private EntityManager em;

    @Resource
    private UserTransaction userTransaction;

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

    }

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

        try {
            String first_name = request.getParameter("firstName");
            String lastName = request.getParameter("lastName");
            String email = request.getParameter("email");
            String date = request.getParameter("hireDate");
            String phoneNumber = request.getParameter("phoneNumber");
            Double monthlySalary = Double.valueOf(request.getParameter("monthlySalary"));

            Employee emp = new Employee();
            emp.setFirstName(first_name);
            emp.setLastName(lastName);
            emp.setSalary(monthlySalary);

            Date dt = new SimpleDateFormat("yyyy-MM-dd").parse(date);
            emp.setHireDate(dt);
            emp.setEmail(email);
            emp.setPhoneNumber(phoneNumber);
           
            userTransaction.begin();
            em.persist(emp);
            userTransaction.commit();

            PrintWriter out = response.getWriter();
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet NewServlet</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>The user " + emp.getFirstName() + " has been registered </h1>");
            out.println("</body>");
            out.println("</html>");

        } catch (ParseException | NotSupportedException |
                SystemException | RollbackException |
                HeuristicMixedException | HeuristicRollbackException |
                SecurityException | IllegalStateException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}


CODE EXPLANATION

@PersistenceContext
    private EntityManager em;

The @PersistenceContext annotation is used in Jakarta EE to inject an EntityManager into a class. Injection is a subject that will explore in more details in later lessons.

The EntityManager is the interface used in Jakarta Persistence to interact with the persistence context (i.e., the database). It allows you to perform CRUD (Create, Read, Update, Delete) operations on entities and manage the persistence lifecycle.

When you annotate a field with @PersistenceContext, it tells the container (like WildFly) to inject the EntityManager into that field automatically at runtime.

@Resource
    private UserTransaction userTransaction;

The @Resource annotation is injecting a UserTransaction object into the class.

UserTransaction is an interface that provides methods to control transactions. It allows you to begin, commit, and roll back a transaction manually.

String first_name = request.getParameter("firstName");

request is an instance of the HttpServletRequest class, which represents the HTTP request sent from the client (usually a web browser) to the server. 

This object contains all the data sent by the client, such as form data, query parameters, and HTTP headers.
getParameter("firstName") is a method of the HttpServletRequest class that retrieves the value of a parameter named "firstName" sent by the client in the HTTP request. Using the getParameter( ) we retrieve all the values sent by the browser to the Servlet.

Employee emp = new Employee();

Employee is the entity class that we've defined in our project. It represents an object that holds data and behaviors related to an employee. The values of the object's properties are coming from the values retrieved from the getParameter( ) method.

userTransaction.begin();
            em.persist(emp);
            userTransaction.commit();

userTransaction is an instance of UserTransaction, which is an interface used for programmatic transaction management in Jakarta EE.

begin() is a method that starts a new transaction. When you call userTransaction.begin(), the container begins a new transaction that will include any operations performed on the database during this transaction.

All the database changes made within this transaction will not be visible to other transactions until the transaction is committed. If something goes wrong and you need to undo the changes, you can rollback the transaction.

em is an instance of EntityManager which is responsible for interacting with the database in a Jakarta Persistence context.

persist(emp) is a method of EntityManager used to save a new entity (in this case, emp, which is an instance of the Employee class) to the database.When you call persist(emp), Jakarta EE Persistence marks the emp object as new and ready to be inserted into the database. The persist() method does not immediately write the object to the database; it schedules the insert operation to occur when the transaction is committed.

The emp object needs to be a Jakarta EE Persistence entity (i.e., it should be annotated with @Entity and have an @Id field for the primary key).

commit() is a method of the UserTransaction interface that commits the transaction to the database.

When you call userTransaction.commit(), all changes made within the transaction (in this case, the persist() operation) are committed and become permanent in the database.

After the commit, the changes made within this transaction are visible to other transactions, and the transaction is considered complete.

       PrintWriter out = response.getWriter();
            out.println("<!DOCTYPE html>");

This line initializes a PrintWriter named out which will be used to send content back to the client. You can use out to write HTML, plain text, or any other type of textual data to the HTTP response.

If the transactions is completed successfully, then we should receive back the response from the Servlet.

SENDING DATA TO SERVLET

In the next lesson, we will add a JSP page to our web application. But for now, we need to test if our Servlet works the way is expected. We can test the functionality of the Servlet by sending data through a REST client tools that exists within the Apache NEtBeans IDE.

First of all, clean and build the application and run it again. While the application is deployed and running on the Wildfly, open the Tools menu and select REST client. If the REST client is not showing, you can install it from the Plugins option.


Select POST from the HTTP methods menu and type next to it the URL address of the Servlet. In my case that will be http://localhost:8080/JakartaEETutorial2-1.0-SNAPSHOT/Controller. 

Then click the Add button and add all the names of the properties incuding their values that you expect the Servlet to read. Click the Send button. The transaction should be successfully completed. 


To verify that we have managed to insert data into the table, we go to the Services section and after we right click on the table we select View Data. 


On this new window, we can execute queries on the database. The View Data actually prepares for us a "select all" query. To execute the query click on the Run SQL button. We should be able to see that the table contains one record of data.


On the next lesson, we will add a JSP page and explain what an MVC model is all about.



full-width

Post a Comment

0 Comments