Monday, 10 February 2014

Simple Calculator Using JSF MVC Primefaces and Ajax

In this tutorial, we will understand how to use MVC Pattern when developing JSF Applications.
Agenda:
1)        @ManagedBean: The Model
2)        @ManagedProperty: The injection of model into controller and achieve loose coupling
3)        @SessionScoped: The controller
4)        Composite Views: Create reusable view components
5)        The view page using primefaces and AJAX
Directory Structure:
1)        Let’s get Start with Model Layer:
Interface:
public interface CalculatorIntf {
    public int add(int a, int b);
    public int sub(int a, int b);
}
Implementing Class:
@ManagedBean(name="calc")
@SessionScoped
public class Calculator implements CalculatorIntf{
    @Override
    public int add(int a, int b) {        return a + b;     }
   @Override
    public int sub(int a, int b) {        return a - b;    }
}
And the Value Object Class:
public class CalculatorVO {
    private int a;
    private int b;
    private int c;
// getters and setters for a, b, c
}
2nd And 3rd steps)The controller Class with Dependency Injection
@ManagedBean
@SessionScoped
public class CalculatorController {
   public void add() {        calculatorVO.setC(calculatorIntf.add(calculatorVO.getA(), calculatorVO.getB()));    }
   public void sub() {        calculatorVO.setC(calculatorIntf.sub(calculatorVO.getA(), calculatorVO.getB()));    }
    public CalculatorIntf getCalculatorIntf() {  return calculatorIntf;     }
    public void setCalculatorIntf(CalculatorIntf calculatorIntf) {     this.calculatorIntf = calculatorIntf;    }

    public CalculatorVO getCalculatorVO() {       
if (calculatorVO == null) {   calculatorVO = new CalculatorVO();        }        return calculatorVO;
    }
    private CalculatorVO calculatorVO;
    @ManagedProperty(value = "#{calc}")    private CalculatorIntf calculatorIntf;}
4)  The Composite View component

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://java.sun.com/jsf/html">
     <cc:interface>
        <cc:attribute name="a" required="true" />
        <cc:attribute name="b" required="true" />
        <cc:attribute name="c" required="true" />
        <cc:attribute name="add" required="true" method-signature="void add()"/>
        <cc:attribute name="subtract" required="true" method-signature="void sub()"/>
    </cc:interface>

    <!-- IMPLEMENTATION -->
    <cc:implementation>
        <p:panel header="Maths Operations">
                <p:panelGrid columns="2">
                    <h:outputText value="Num 1: " />
                    <h:inputText value="#{cc.attrs.a}">
                        <p:ajax event="blur" />
                    </h:inputText>
                    <h:outputText value="Num 2: " />
                    <h:inputText value="#{cc.attrs.b}">
                        <p:ajax event="blur" />
                    </h:inputText>
                    <h:commandButton value="Add" >
                        <p:ajax event="click" listener="#{cc.attrs.add}" update="result" />
                    </h:commandButton>
                    <h:commandButton value="Sub" >
                        <p:ajax event="click" listener="#{cc.attrs.subtract}" update="result" />
                    </h:commandButton>
                    <h:outputText value="Result: "/>
                    <h:outputText id="result" value="#{cc.attrs.c}"/>
                </p:panelGrid>
            </p:panel>
    </cc:implementation>
</html>
Note: Do remember that <cc:attribute name="sub" .... ... /> will not work. so made it subtract
5) The View Page:
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:m="http://java.sun.com/jsf/composite/com/shared">
    <h:head>
        <title>Calculator App</title>
    </h:head>
    <h:body>
        <h:form>
<m:mathsComponent a="#{calculatorController.calculatorVO.a}"
                  b="#{calculatorController.calculatorVO.b}"
                  c="#{calculatorController.calculatorVO.c}"
                  add="#{calculatorController.add}"
                  subtract="#{calculatorController.sub}"/>
                            
        </h:form>
    </h:body>
     </html> 
Conclusion:
1) Controllers can depend upon interface references than direct implementations with the help of @ManagedProperty Attribute. Thus making our application Loosely coupled.
2) Do not use sub as attribute, because sub seems to be a reserved word in JSF
3) Creating composites will help us reuse the components at many places.





Monday, 6 May 2013

Upload File and send text field values using JSF and Primefaces


In my previous post, I showed how to upload a file using JSF and primefaces.
In this blog I will show how to upload a file along with text field value.
In this blog I will add a text field to the form and a field in the controller with setters and getters. So to transfer text field value to the controller, I will add an event to text field to update the managed bean on blur event.

 <h:form enctype="multipart/form-data">
<h:outputLabel value="Text Field here"/>
 <h:inputText value="#{fileUploadController.summary}">
<f:ajax event="blur"/>
</h:inputText>
<p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload}"
mode="advanced" update="messages, dt"  auto="true"/>
 <p:dataTable id="dt" var="filename" value="#{fileUploadController.filesList}">
<p:column>
 #{filename}
 </p:column>
 </p:dataTable>
<p:growl id="messages" showDetail="true"/>

 </h:form>



@ManagedBean
@SessionScoped
public class FileUploadController implements Serializable {

    private String summary;
    private List<String> filesList;

    public List<String> getFilesList() {
        return filesList;
    }

    public void setFilesList(List<String> filesList) {
        this.filesList = filesList;
    }

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public FileUploadController() {
        filesList = new ArrayList<String>();
    }

    public void handleFileUpload(FileUploadEvent event) {
        FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded. Textfield: "+summary);
        FacesContext.getCurrentInstance().addMessage(null, msg);
        UploadedFile file = event.getFile();
        System.out.println(file.getContents());
        filesList.add(file.getFileName());
        System.out.println("added to files list " + filesList + " with Summary field " + summary);
    }
}


And the result:


Uploading file Using JSF Primefaces

Following steps are involved in developing upload functionality in JSF and primefaces:

1) Add the file-upload library to project and configuring web.xml file
2) Writing the File Upload handler controller and maintaining a List of files uploaded
3) Writing the xhtml page for uploading a file and Datagrid to show the list of files uploaded

Let us start:

1) Add the file-upload library to project



       and configuring web.xml file

     <filter>
        <filter-name> File Upload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
        <init-param>
            <param-name>thresholdSize</param-name>
            <param-value>51200</param-value>
        </init-param>
        <init-param>
            <param-name>uploadDirectory</param-name>
            <param-value>D:\uploadedFiles</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name> File Upload Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>




2) Writing the File Upload Controller

@ManagedBean
@SessionScoped
public class FileUploadController implements Serializable {

    private List<String> filesList;
    public List<String> getFilesList() {
        return filesList;
    }

    public void setFilesList(List<String> filesList) {
        this.filesList = filesList;
    }

    public FileUploadController() {
        filesList = new ArrayList<String>();
    }

    public void handleFileUpload(FileUploadEvent event) {
        FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
        FacesContext.getCurrentInstance().addMessage(null, msg);
        UploadedFile file = event.getFile();
        filesList.add(file.getFileName());
        System.out.println("added to files list " + filesList);
    }
}


3) Writing the xhtml page for uploading a file

<p:layoutUnit position="center">
<h:form enctype="multipart/form-data">

<p:fileUpload fileUploadListener="{fileUploadController.handleFileUpload}"
mode="advanced" update="messages, dt"
auto="true"/>
<p:dataTable id="dt" var="filename" value="#{fileUploadController.filesList}">
<p:column>
#{filename}
</p:column>
</p:dataTable>
<p:growl id="messages" showDetail="true"/>

</h:form>
</p:layoutUnit>


Result

Friday, 5 April 2013

Create Login Page with JSF

Steps in creating this example:

1) Create a Template page
2) Create a JSF Web page with two fields namely username and password
2.1) Page will have a command button to check login
2.2) Action on command button (with Ajax enabled) invokes the controller to validate the login against database
2.3) Status of login is updated in the output label.
3) Creating Entity Class
4) Controller invokes named query to check the database and yields result

1) Create Template
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="
http://www.w3.org/1999/xhtml"
      xmlns:ui="
http://java.sun.com/jsf/facelets"
      xmlns:h="
http://java.sun.com/jsf/html">
    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title><ui:insert name="title">Default Title</ui:insert></title>
        <h:outputStylesheet name="css/jsfcrud.css"/>
    </h:head>

    <h:body>
        <p>
            <ui:insert name="body">Default Body</ui:insert>
        </p>
    </h:body>

</html>


2) Create Client page with Username and password fields

<ui:composition template="template.xhtml"
                xmlns:ui="
http://java.sun.com/jsf/facelets"
                xmlns:h="
http://java.sun.com/jsf/html"
                xmlns:f="
http://java.sun.com/jsf/core">
    <ui:define name="title">Welcome, Please Login</ui:define>
    <ui:define name="body">
        <h:form>
           
            <h:panelGrid style="float: right; border: 1">
                <h:outputText value="Login!!" />
                <h:outputText value="Username"/>
                <h:inputText value="#{logintblController.selected.username}" />
                <h:outputText value="Password" />
                <h:inputSecret  value="#{logintblController.selected.password}" />
                <h:commandButton action="#{logintblController.validateLogin}" value="Login">
                    <f:ajax execute="@form" render="displayResponse" />
                </h:commandButton>
                <h:outputLabel id="displayResponse" value="#{logintblController.message}" />
            </h:panelGrid>
        </h:form>
    </ui:define>
</ui:composition>

3)Entity Class:

@Entity
@Table(name = "LOGINTBL")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Logintbl.findByUsernameAndPassword",
        query = "SELECT l FROM Logintbl l where l.username = :username "
        + "and l.password= :password")
    })
public class Logintbl implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "USERID")
    private Integer userid;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 20)
    @Column(name = "USERNAME")
    private String username;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 25)
    @Column(name = "PASSWORD")
    private String password;

    ... setter and getter methods

4) Controller Class:

@ManagedBean(name = "logintblController")
@SessionScoped
public class LogintblController implements Serializable {

    private Logintbl current;
    @EJB
    private com.jsf.blog.example1.LogintblFacade ejbFacade;
    private String message;

    public LogintblController() {
    }

    public Logintbl getSelected() {
        if (current == null) {
            current = new Logintbl();
        }
        return current;
    }

    private LogintblFacade getFacade() {
        return ejbFacade;
    }

    public void validateLogin() {
        TypedQuery<Logintbl> query = getFacade().getEntityManager().
                createNamedQuery("Logintbl.findByUsernameAndPassword", Logintbl.class);
        query.setParameter("username", current.getUsername());
        query.setParameter("password", current.getPassword());
        try {
            Logintbl login = query.getSingleResult();
            message = "Valid User";
        } catch (Exception e) {
            message = "Invalid Login Credentials";

        }
    }
    public String getMessage() {
        return message;
    }
}


Result: