What is Servlet

What is servlet? A servlet is a Java class which can be accessed by via request-response methods.

This application is designed to demonstrate a distributed system development which uses servlets and  EJBs. The project consists of two servlets including Registration which handles login and register processes and Shop servlet which handles all the functionalities related to the shop applications such as product list and shopping basket.

License: MIT License, download link is available at the end of this article.

There are several JSP pages which provide UI and graphics and forms to allow users communicate with servlets. Requests will be sent to the servlets and servlets connect to the EJB components to perform the task. EJBS connect to the data store (hypersonic in this example) to store, update or fetch the data and return it to the servlets. These data will be sent to the JSP pages again and displayed to the user, the graph below represents how this project communicate with different components:

Distributed-Systems

It is an easy task to change the data source from hypersonic to any database servers such as MySQL or Oracle if required.

Definitions and reasoning

Entity Beans

The case study use case diagram defines 2 entities for this project which includes Customer and Product, so two EJB entity beans has been developed. According to the case study, since a login facility is required, Customer entity bean should at least contain id, username and a password property plus a validatePIN method.

Product entity bean contains id, name and price. However since we need a method to find out if we have enough items in the stock, we need to add quantity property to this entity bean as well. This method gets a number and checks with quantity property and returns a boolean value which indicates if there are enough stock available for this item or not. Similarly, purchase method is implemented to reduce quantity by number of provided items to reduce it from the stock. Both of these entity beans will be mapped to tables (customer and product) to update the table in the data source defined in the persistence unit.

Following annotations has been used in these entity beans and reasons are explained:

  • @Id: Used to define the id field as identifier for these entity beans. This field acts as a primary key.
  • @Table: Defines table name for each entity bean to be used by persistence units.
  • @Column(name = “xxx”): defines column name for each attribute in the database, xxx to be replaced by the database field name for each attribute.
  • @GeneratedValue(strategy = GenerationType.AUTO): used with @Id annotation to make the id column auto number, so in the database each new record contains a unique id number which will be incremented.
  • @Override: This annotation is used in some methods which declared in their super classes to tell the compiler to override the element.

Session Beans

There are 2 stateless session beans in this project and no statefull session beans. For shopping basket we will use servlet session object which will be handled by the application server. Here are our session beans:

RegistrationBean which consist of two methods, one for register data and one for validate customer login. It is defined as stateless and here are annotations for this bean:

  • @Stateless(name = “registration”): Defines this session bean as stateless and map it to the registration name. This name will be used to lookup this session bean via initial context.
  • @Remote(RegistrationBean.class): Defines  remote interface of this class and also allows remote lookup to access this session bean.
  • @Local: Allows local lookup to be performed to access this beans.
  • @PersistenceContext: causes the entity manager to obtain an instance.

ShopBean which contains 5 methods to handle shop related functionalities. These methods provide a list of features including: get list of all the products, find a product by  id, add a new product, buy product and checkout. It is also stateless because we do not need to keep any state of products in this session bean and shopping basket will be handled by servlet sessions. Here are the annotations used in this session bean:

  • @Stateless(name = “shop”): Defines this session bean as stateless and map it to the sho name. This name will be used to lookup this session bean via initial context.
  • @Remote(ShopBean.class): Defines  remote interface of this class and also allows remote lookup to access this session bean.
  • @Local: Allows local lookup to be performed to access this beans.
  • @PersistenceContext: causes the entity manager to obtain an instance.

Servlets

There are 2 servlets in this project which communicate with session beans and return the result to the JSP pages.

  • Registration Servlet
    First servlet is Registration which handles register and login features of the project, This servlet has been mapped in the web.xml file defined in the WEB-INF folder to /Registration URL. This servlet uses HttpSession class to access users session data to store login details of the user so we know if user is already logged in or not.
  • Shop Servlet
    Shop servlet handles all other shop functionalities such as loading list of the products, adding product in the basket and checkout. This servlet also mapped to /Shop URL defined in the web.xml file. Shop servlet also uses HttpSession class to access users session to store shopping basket object and also check if the user is already logged in and get user’s details as well.

JSP Pages

There are 4 main jsp pages in this project including: index.jsp, products.jsp, item.jsp and basket.jsp. Also footer.jsp contains footer notes and header.jsp which contains menu and header graphics are included in all of these 4 pages. Using include tag. Here is an overall structure of the JSP pages:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Page title</title>
</head>
<body>
<div id=”wrapper”>
<%@include file="header.jsp" %>
Contents take place here
<%@include file="footer.jsp" %>
</div>
</html>
  • Index.jsp
    This page is the default page and contains registration and login form. Action attribute of both forms are set to “/TVUShop/Registration” which will cause the data to be posted to the Registration servlet.
  • Products.jsp
    This page provides list of all the products in the stock and allows user to select a product. In order to access this page, customer must register first and then login. After login user will be redirected to the “/TVUShop/Shop” servlet which explained earlier. This servlet gets list of the products from Shop session bean and sets the result in the products attribute:
// Get products collection
Collection<Product> products = shop.getProducts(keyword);
 // store the product in the products attribute
request.setAttribute("products", products); 
// load products.jsp page with products attribute
RequestDispatcher requestDispatcher = getServletContext().getRequestDispatcher ("/products.jsp");
requestDispatcher.forward(request, response);

Using requestDispatcher, request will be forwarded to the products.jsp page so list of the products will be accessible in that page:

// Get collection of all the products in the database
Collection<Product> products = (Collection) request.getAttribute("products");

// Default error message
String msg = "";

// If no product is retreived, display a message
if(products.isEmpty()){
msg = "Your search did not match any items.";
}

Using a for loop products will be written on the web page:

// loop through all the products
for(Product product: products){

// print product details on the webpage
out.println("<a href='Shop?action=displayItem&id=" + product.getId() + "'>
<img   src='products/" + product.getPicture() + "' alt='" + product.getName() + "'height='120' /></a>");
…
}
  • Item.jsp
    When user selects a product, this page appears which contains product details and a form to let user add the product to the shopping cart by entering quantity. This page will be accessible through “TVUShop/Shop” servlet, however this time action variable from the products page will send “displayItem” value with an “id” number to indicate the product id:

    http://127.0.0.1:8080/TVUShop/Shop?action=displayItem&id=2

    Shop servlet detects this request using following condition:

    // display a product by given id
    if (action.equals("displayItem")) {
    // get product by id
      Product item = shop.findProduct(id);
    // store item in the attributes and open item.jsp page
    request.setAttribute("item", item);
                        RequestDispatcher requestDispatcher = getServletContext().getRequestDispatcher("/item.jsp");
                      requestDispatcher.forward(request, response);
    }
  • Using ShopBeanImpl session bean, Shop servlet fetches the product from database by id and adds it to the request attributes and then forward it to the item.jsp page. This page can now get product details and display it on the screen:
    // Get selected product
    Product item = (Product) request.getAttribute("item");
  • Basket.jsp
    This page will provide shopping basket items for the user and allow them to choose to empty the basket or checkout. This page will be accessible via “/TVUShop/Shop” servlet. When action querystring is set to “basket” this servler will get shopping basket from user session data and forward the request to the basket.jsp page:

     http://127.0.0.1:8080/TVUShop/Shop?action=basket
    if (action.equals("basket")) {
    // If emtpy cart button is clicked, remove basket session
    
    if (request.getParameter("btnEmpty") != null) {
      session.removeAttribute("basket");
    }
        // open basket.jsp page
        RequestDispatcher requestDispatcher =     getServletContext().getRequestDispatcher("/basket.jsp");
    requestDispatcher.forward(request, response);
    }

Basket page then gets basket attribute using following code:

// Get shopping basket from users session
ArrayList<Product> basket = (ArrayList<Product>) session.getAttribute("basket");

// If basket is null, set it to an empty arraylist
if ( basket == null){
  basket = new ArrayList<Product>();
}

Configuration files

Configuration files structure

  • application.xml
    Java EE Deployment Descriptor which identifies the application description, modules and web URIs. This file is located inside the META-INF folder of the ear file:
<application>
  <display-name>TVUShop EJB</display-name>
  <module>
    <web>
        <web-uri>tvushop.war</web-uri>
        <context-root>/TVUShop</context-root>
    </web>
  </module>
  <module>
    <ejb>tvushop.jar</ejb>
  </module>
</application>
  • persistence.xml
    Defines persistent unit to be accessed by the entity manager. The java:/DefaultDS  points to the HSQL DB which is embedded inside the JBoss. This file located in the META-INF folder of the .jar file. This jar file contains entity bean and session beans:
<?xml version="1.0" encoding="UTF-8"?>
<persistence>
  <persistence-unit name="TVUShopEJB">
    <jta-data-source>java:/DefaultDS</jta-data-source>
    <properties>
        <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
    </properties>
  </persistence-unit>
</persistence>
  • jboss-web.xml
    Defines the context-root in the EAR file for the web applications. Also another way to define this context root is in the application.xml file.This file is located inside the war/WEB-INF folder:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<context-root>/TVUShop</context-root>
</jboss-web>
  • web.xml
    This file defines the servlets and servlets mappings in the web application .war files. This file is located inside .war/WEB-INF folder:
<web-app>
  <description>TVUShop EJB</description>
  <!-- ### Servlets -->
  <servlet>
    <servlet-name>Registration</servlet-name>
    <servlet-class>server.servlet.Registration</servlet-class>
  </servlet>  
  <servlet>
    <servlet-name>Shop</servlet-name>
    <servlet-class>server.servlet.Shop</servlet-class>
  </servlet>
  <!-- The servlet and jsp page mappings -->
  <servlet-mapping>
    <servlet-name>Registration</servlet-name>
    <url-pattern>/Registration</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Shop</servlet-name>
    <url-pattern>/Shop</url-pattern>
  </servlet-mapping>
</web-app>
  • Build.xml
    This file is not a part of the EAR files, however it is used for building and compiling the project by Apache ant. This file compiles all the classes and make .jar, .war and .ear archives.

Deployment and testing

To deploy the project, you should copy tvushop.ear in the jboss/server/default/deploy folder, following screen shot demonstrate tvushop.ear successful deployment on the jboss:

JBoss Application Server

Testing

Now you can access the default TVUShop page at the following URL:

http://127.0.0.1:8080/TVUShop/

ServletDownload Link: Download TVUShop.zip

About majid

Software engineer, Web developer and IT graduate. Profile: View My Profile
This entry was posted in Scripts, Tutorials. Bookmark the permalink.