Saturday, August 20, 2016

Shopping Cart Example with EJB 3 and GlassFish 3 - Stateful Session Bean and Remote Client

The cart example represents the operations of a shopping cart in online bookstore. This example uses

1. Java Enterprise Application (Cart)

2. Remote Business Interface (Cart.java)

3. Session Bean Class (CartBean.java)

4. Two Helper classes (BookException.java and IdVerifier.java)

5. A servlet client (CartClient.java)


Before continue this post, please go through previous post of Enterprise Application with EJB and Dependency Injection.


1. Java Enterprise Application (Cart)



Create Java EE application using  NetBeans. File -> New Project -> Java EE -> Enterprise Application. And name it Cart. And choose GlassFish server. This will create 3 nodes in Projects explorer: Cart, Cart-ejb, Cart-war.


2. Remote Business Interface (Cart.java)

Create Cart.java in cart.ejb package under Cart-ejb node.
Cart.java is a plain java interface that defines all business methods implemented in the bean class. If a bean class implements a single interface, this interface is assumed to be business interface. Otherwise if bean class implements more than 1 interface then the business interface must be explicitly annotated. The business  interface can be annotated with @Remote (javax.ejb.Remote) or @Local (javax.ejb.Local). If not annotated anything, the interface is local. 

In this example, the interface is remote. The following interfaces are excluded when any bean class implements more than 1 interface: java.io.Serializable , java.io.Externalizable and any inteface under javax.exjb package.

The source code of Cart.java interface:


package cart.ejb;

import cart.util.BookException;
import java.util.List;
import javax.ejb.Remote;

/**
 *
 * @author Khan.Ashik
 */
@Remote
public interface Cart {
   
    public void initialize(String person) throws BookException;
   
    public void initialize(String person, String id) throws BookException;
   
    public void addBook(String title);
   
    public void removeBook(String title) throws BookException;
   
    public List<String> getContents();
   
    public void remove();
   
}


3. Session Bean Class (CartBean.java)

Create CartBean.java in cart.ejb package under Cart-ejb node.

■ The class is annotated with @Stateful  and implements the methods of Cart.java interface.

■ Since it is a stateful session bean, it can implement any optional lifecycle callback methods annotated  with @POstConstruct, @PreDestroy, @PostActivate and @PrePassivate.

■ It also can implment any optional business method annotated @Remove.



The source code of CartBean.java class:


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cart.ejb;

import cart.util.BookException;
import cart.util.IdVerifier;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Remove;
import javax.ejb.Stateful;

/**
 *
 * @author Khan.Ashik
 */
@Stateful
public class CartBean implements Cart{

    List<String> contents;
    String customerId;
    String customerName;
   
    @Override
    public void initialize(String person) throws BookException {
        if(person==null)
        {
            throw new BookException("Null person not aalowed.");
        }
        else
        {
            customerName = person;
        }
        customerId = "0";
        contents = new ArrayList<String>();
    }

    @Override
    public void initialize(String person, String id) throws BookException {
        if(person==null)
        {
            throw new BookException("Null person not aalowed.");
        }
        else
        {
            customerName = person;           
        }
       
        IdVerifier idChecker = new IdVerifier();
       
        if(idChecker.validate(id))
        {
            customerId = id;
        }
        else
        {
            throw new BookException("Invalid Id: " + id);
        }
       
       
        contents = new ArrayList<String>();
    }

    @Override
    public void addBook(String title) {
        contents.add(title);
    }

    @Override
    public void removeBook(String title) throws BookException {
        boolean result = contents.remove(title);
       
        if(result==false)
        {
            throw new BookException("\"" + title + "\" not in the cart.");
        }
    }

    @Override
    public List<String> getContents() {
        return contents;
    }

    @Remove
    public void remove() {
        contents = null;
    }
   
}


4. Helper Classes (BookException.java and IdVerifier.java)

Create BookException.java and IdVerifier.java in cart.util package under Cart-ejb node.

CartBean has 2 helper classes. BookException is thrown by removeBook method and IdVerifier validates the customer Id.

The source code of BookException.java class:

package cart.util;

/**
 *
 * @author Khan.Ashik
 */
public class BookException extends Exception{

    public BookException() {
    }

    public BookException(String message) {
        super(message);
    }
   
   
   
}

The source code of IdVerifier.java class:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cart.util;

/**
 *
 * @author Khan.Ashik
 */
public class IdVerifier {

    public IdVerifier() {
    }
   
    public boolean validate(String id)
    {
        boolean result = true;
       
        for(int i=0; i        {
            if(Character.isDigit(id.charAt(i))==false)
            {
                result = false;
            }
        }
        return result;
    }
}


4. Servlet Client (CartClient.java)

Create CartClient.java in cart.client package under Cart-war node.

Here we inject CartBean by annotating  @EJB to Cart interface to get a new reference to the enterprise bean.

The code snippet is:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cart.client;

import cart.ejb.Cart;
import cart.util.BookException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author Khan.Ashik
 */
@WebServlet(name="CartServlet", urlPatterns="/clientServlet")
public class CartClient extends HttpServlet{

    @EJB
    private Cart cart;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       
        PrintWriter writer = resp.getWriter();
        try {
            cart.initialize("MY BOOK", "123");
            cart.addBook("Head First");
            cart.addBook("Bean Developer");
            cart.addBook("Street Show");
           
            List bookList = cart.getContents();
           
            Iterator iterator = bookList.iterator();
           
            while(iterator.hasNext())
            {
                String title = iterator.next();
                writer.write("Retrieving book title from cart: " + title+"\n");
            }
           
            writer.write("Removing \"MY BOOK\" from cart\n");
           
            cart.removeBook("MY BOOK");
           
            cart.remove();
           
           
           
        } catch (BookException ex) {
            writer.write("Caught a BookException: " + ex.getMessage());
           
        } catch (Exception ex) {
            writer.write("Caught an unexpected exception!");
            ex.printStackTrace();
           
        }
    }
   
   
   
}


Deploy and run the application. Go to servlet URL to get the output of the bean.

And thats all about this example.









Sunday, August 7, 2016

Enterprise Application with EJB and Dependency Injection

Here we'll see a simple JAVA EE application named converter. The purpose of converter is to calculate currency conversions between dollar, taka and ringit. The converter application consists of an enterprise bean, which performs the calculations, and a web client.

Platforms:

1. GlassFish Server

2. NetBeans


Overview:

1. Create Enterprise Application: Converter
2. Create the enterprise bean: ConverterBean.
3. Create the web client.
4. Deploy converter.ear into the server.
5. Using a browser, run the web client.

1. Create Enterprise Application: Converter.
Go to File->New Project (Ctrl + Shift + N) and follow following steps.










After clicking Finish, three project nodes will be created:  Converter, Converter-ejb, Converter-war.

2. Now i'll create a class named ConverterBean under Converter-ejb node. This is an Enterprise Bean by @Stateless annotation. This class implements 2 business methods dollarToTaka and takaToRingit. Because the enterprise bean class doesn't implement a business interface, the enterprise bean exposes a local, no-interface view. The public methods in the enterprise bean class are available to clients that obtain a reference to ConverterBean. The source code is as follows:




package converter.ejb;

import java.math.BigDecimal;
import javax.ejb.Stateless;


@Stateless
public class ConverterBean {
    private BigDecimal takaRate = new BigDecimal("80");
    private BigDecimal ringitrRate = new BigDecimal("0.054");
   
    public BigDecimal dollarToTaka(BigDecimal dollars)
    {
        BigDecimal result = dollars.multiply(takaRate);
       
        return result.setScale(2, BigDecimal.ROUND_UP);
    }
   
    public BigDecimal takaToRingit(BigDecimal taka)
    {
        BigDecimal result = taka.multiply(ringitrRate);
       
        return result.setScale(2, BigDecimal.ROUND_UP);
    }
}


3. Now i'll create a servlet named ConverterServlet and modify the index.jsp under Converter-war node. A JAVA servlet is a web component that responds to HTTP request.

The main part of ConverterServlet class is that it uses dependency injection to obtain a reference to ConverterBean. The javax.ejb.EJB annotation is added to the declaration of the private member variable converterBean, which is of type ConverterBean. ConverterBean exposes a local, no-interface view, so the enterprise bean implementation class is the variable type. 

The source code of ConverterServlet is as follows:




 package com.servlets;

import converter.ejb.ConverterBean;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import javax.ejb.EJB;
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(name="ConverterServlet", urlPatterns="/convert")
public class ConverterServlet extends HttpServlet {

    @EJB
    ConverterBean converterBean;
   
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        writer.write("Invalid Access");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        RequestDispatcher dispatcher =  req.getRequestDispatcher("index.jsp");
       
        String dollarText = req.getParameter("dollar");
        if(dollarText.isEmpty() || dollarText==null)
        {
            req.setAttribute("error", "Please Give Dollar Amount");
            dispatcher.forward(req, resp);
        }
       
        try
        {
            BigDecimal dollar = new BigDecimal(dollarText);
           
            BigDecimal taka = converterBean.dollarToTaka(dollar);
           
            BigDecimal ringit = converterBean.takaToRingit(taka);
           
            req.setAttribute("dollar", dollar);
            req.setAttribute("taka", taka);
            req.setAttribute("ringit", ringit);
            //System.out.println(dollar + "~" + taka  + "~" + ringit);
        }
       
        catch(Exception e)
        {
            req.setAttribute("error", "Number Required"); 
            //e.printStackTrace();
            //System.out.println(e.getMessage());
        }
       
       
        dispatcher.forward(req, resp);
    }
   
}

The index.jsp file is as follows:




<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Convert Currency</title>
    </head>
    <body>
        <h1>Convert Currency!</h1>
      
        <form action="./convert" method="post">
          
            <table>
              
                <tr>
                    <td>Dollar: </td>
                    <td><input type="text" name="dollar" value="${dollar}"/>${error}</td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="Convert"/>
                    </td>
                </tr>
                <tr>
                    <td>
                        Taka:
                    </td>
                    <td>
                        ${taka}
                    </td>
                </tr>
                <tr>
                    <td>
                        Ringit:
                    </td>
                    <td>
                        ${ringit}
                    </td>
                </tr>
              
            </table>

              
          
        </form>
    </body>
</html>

4. Now clean and build the Converter to create Converter.ear and deploy it into GlassFish Server.

5. Run using default port i.e  http://localhost:8080/Converter-war/ And test the application.






That's all about this example.