Wednesday, June 29, 2016

Enterprise Java Bean: Stateless and Stateful Session Bean Example


Stateless Session Bean

Acts like global variable of a program. It does not preserve client state. Stateless bean objects are pooled by the container. And value of object retained the whole application scope until modified by another client. That means each instance of bean will get same reference and same modified value.


Stateful Session Bean:

Acts like local variable. It preserves client state i.e. conversational state of multiple method calls. That means each new instance will get different reference and value.

Now we'll see example of Stateless and Stateful Bean. And a remote client to call them.

1. Create EJB Project

2. Create Remote interface using @Remote annotation.

3. Create Stateless Session Bean using @Stateless annotation and Stateful Session Bean using @Stateful annotation - Both are implmenting same remote interface for simplicity.

4. Create web application client MyEJBWebClient to test the beans.

5. Test Stateless Session Bean where we'll see value is retain in every instance of the bean that means same reference are getting in whole application.

6. Test Stateful Session Bean where we'll see that new reference is getting from each new instance so value would be different. 





 1. Create EJB Project named MyEJB in following way







 2. Create a Remote interface using javax.ejb.Remote annotation.



@Remote
public interface BankRemote {

    boolean withdraw(int amount);

    void deposit(int amount);

    int getBalance();
}




3. Create Stateless and Stateful Session Bean with name using  @Stateless (mappedName="") and @Stateful(mappedName="") annotation and both are implementing BankRemote interface.

// define custom name for stateless session bean
@Stateless(mappedName="stateless123")
public class BankSateless implements BankRemote {

    private int amount = 0;
    @Override
    public boolean withdraw(int amount) {
        if(amount<=this.amount)
        {
            this.amount-=amount;
            return true;
        }
        else
        {
            return false;
        }
    }

    @Override
    public void deposit(int amount) {
        this.amount+=amount;
    }

    @Override
    public int getBalance() {
        return amount;
    }     
}


// define custom name for stateful session bean
@Stateful(mappedName="sateful123")
public class Bank implements BankRemote{

    private int amount = 0;
    @Override
    public boolean withdraw(int amount) {
        if(amount<=this.amount)
        {
            this.amount-=amount;
            return true;
        }
        else
        {
            return false;
        }
    }

    @Override
    public void deposit(int amount) {
        this.amount+=amount;
    }

    @Override
    public int getBalance() {
        return amount;
    }
   
}



4. Clean and build MyEJB project. Now create a simple web application named MyEJBWebClient and add MyEJB jar.




-- Go to properties of MyEJBWebClient and add MyEJB.jar.



5. Now we will create a servlet which will take parameter amount and call BankRemote interface by JNDI lookup stateless123. And create index.jsp to call servlet.


<html>
    <head>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Hello World!</h1>
        <form action="./DepositController">
            Enter Amount: <input name="amount" type="text"/> <br/>
            <input type="submit" value="Deposit"/>
            <input type="hidden" name="type" value="deposit"/>
        </form>
        Balance: ${balance}
    </body>
</html>





@WebServlet("/DepositController")
public class BankAction extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            InitialContext ctx = new InitialContext();
            BankRemote b = (BankRemote) ctx.lookup("stateless123");
           
            int amount =  Integer.valueOf(req.getParameter("amount")) ;
           
            b.deposit(amount);
           
            req.getSession().setAttribute("balance", b.getBalance());
           
        } catch (NamingException ex) {
            Logger.getLogger(BankAction.class.getName()).log(Level.SEVERE, null, ex);
        }
        req.getRequestDispatcher("/index.jsp").forward(req, resp);
       
    }
   
}

Deploy and run the MyEJBWebClient project. Here we'll see that balance is increasing after deposit amount. The balance is same in every session.
6.  Now use stateful session bean in servlet

@WebServlet("/DepositController")
public class BankAction extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            InitialContext ctx = new InitialContext();
            BankRemote b = (BankRemote) ctx.lookup("stateful123");
           
            int amount =  Integer.valueOf(req.getParameter("amount")) ;
           
            b.deposit(amount);
           
            req.getSession().setAttribute("balance", b.getBalance());
           
        } catch (NamingException ex) {
            Logger.getLogger(BankAction.class.getName()).log(Level.SEVERE, null, ex);
        }
        req.getRequestDispatcher("/index.jsp").forward(req, resp);
       
    }
   
}
 
Deploy and run the MyEJBWebClient project. Here we'll see that balance is not increasing. It is same as deposit amount for each session i.e. when user press deposit button.






Monday, June 20, 2016

Quick Solution: Download csv file in JSF 2

In xhtml file, I use primefaces command button. You can also use h:commandButton.

<h:form>
<p:commandButton  value="Download File" action="#{branchDownload.download}"
                                 ajax="false"         /> 

 </h:form>

In Managed Bean class, download() method is as follows:

@ManagedBean
@RequestScoped
public class BranchDownload {
// Your code

// download method
public void download()
    {
        String file_name =  "FILE.csv" ;
       
        FacesContext fc = FacesContext.getCurrentInstance();
        ExternalContext ec= fc.getExternalContext();
        ec.responseReset();
        ec.setResponseContentType("text/csv");
        ec.setResponseHeader("Content-Disposition", "attachment; filename=\""+file_name + "\"");
       
        BufferedOutputStream csvOut;
        try {
            csvOut = new BufferedOutputStream(ec.getResponseOutputStream());
            BufferedWriter csvWriter = new BufferedWriter(new OutputStreamWriter(csvOut, "UTF-8"));
       
            csvWriter.append("1,2,3,4,5,6,7,8");
            csvWriter.append("\n");
            csvWriter.flush();

            csvWriter.append("One,2,Three,4,5,6,7,8");
            csvWriter.append("\n");
            csvWriter.flush();

            csvWriter.close();
            csvOut.close();
        } catch (IOException ex) {
            Logger.getLogger(BranchDownload.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally{
            fc.responseComplete();
        }
      
    }
// End download method

}



Simple Technique: How to implement @Singleton annotation in a class

If the class has @Singleton annotation, then your purpose would not solved.

@Singleton
public class MyClass { 
// Code
}
 
Because no annotation can prevent a class having public contructor being instantiated.
 
Just use following technique to your class being instantiated at most once 
in an application.
 
public class MyClass {
    private static MyClass instance = null;

    private MyClass() {
    }
    
    public static MyClass getInstance()
    {
        if(instance == null)
        {
            instance = new MyClass();
        }
        return instance;
    }
} 
 
 
 

Saturday, June 11, 2016

Quick Solution: Injecting one managed bean into property of another managed bean in JSF 2.0

I've One managed bean RegistrationBean  where all of my variable mapped to XHTML file.

And I want to inject / include this bean into RegistrationController bean.

For this purpose I use @ManagedProperty annotation in RegistrationController.

This annotation is used to DI (Dependency Injection) one managed bean into a property of another managed bean.

Lets see the example.

Registration.xhml [Few Parts]


RegistrationBean.java [Few Parts]



RegistrationController.java [Mandatory parts]


Hope you understand.....



Friday, June 3, 2016

Quick Solution: JSF 2 template itself shows style, but template client shows plain text without style

Problems:

I am trying to use JSF Facelet template/Facelet template client first time. I am creating template and template client with Netbeans 7.2.1. When I run that created JSF project and call http://localhost:8080/jpaweb/template.xhtml I can see template style, but when I call client template http://localhost:8080/jpaweb/client.xhtml I see plain text without style. Both files are in the same directory and created by Netbeans wizard. 


template.xhtml



client.xhtml



Answer


Solved. Changed value of web.xml file in url-pattern fieldof Faces Servlet  from /faces/* to *.xhtml, and that worked OK.