Saturday, September 14, 2013

EJB3/JSF2/Primfaces-3.5:uploading and retrieving blob images from database using Eclipse

Until today I did not find a complete tutorial described this full operation despite its importance to most of JSF developers, so I decided to create one including the source code built using Eclipse and deployed to glassfish as described in our tools that we will use in the first post from here

My readers from the previous posts know that we will use the sample hr schema of oracle database for all our posts.So In this sample application we have a primfaces datatable that lists all the employees for this schema,when you press show Image button for any employee you will navigate to another page where it will display the employee's full name plus his blob image retrieved from database.If the employee has not an image you are allowed to upload one.After checking the Image size and type,we insert the image to the database, display it to the user,and prevent him from uploading any more images for this employee as every one should have a unique image. 

in our  post  I will  explain every detail found in the code then I will explore the application- how it works -and in the end of this post you will find the source code to download but note that I will not explain once more the basics about creating the application such as how to connect to database to generate the entities, how to create JSF or EJB project, how to configure the JNDI datasource for oracle database in glassfish 3.1.2 server, how to package your application in an Ear file and so on because all these basics had been explained in details in our previous first posts from here and here

First: Exploring the Application

1-the Database:

The sample hr schema has already the Employees table, so we will create the Images table which has the details of image.The ID_OF_EMPLOYEE column in the Images table is a foreign key for the employees table and also this column has a unique constraint as every employee should have only one Image

script of Images table:
 create table Images (Image_id NUMBER(10),ID_OF_Employee NUMBER(10) unique,  
 Image_name VARCHAR2(200 CHAR) NOT NULL,Image BLOB NOT NULL,  
 Image_type VARCHAR2(100 CHAR) NOT NULL,CONSTRAINT IMAGES_TABLE_PK PRIMARY KEY  
  (  
   Image_id  
  )  
  ENABLE  
 )  
 ALTER TABLE IMAGES ADD CONSTRAINT IMAGES_EMPLOYEE_ID_FK FOREIGN KEY (ID_OF_Employee)  
 REFERENCES EMPLOYEES  
 (  
 EMPLOYEE_ID  
 )  
  ENABLE  
 ;  
Also we create a database sequence as Image_Id column get its value from this sequence.The script of the sequence should be:
 CREATE SEQUENCE Images_Seq INCREMENT BY 50 START WITH 50   
 MAXVALUE 99999999999999 MINVALUE 10 nocache;  

2-EJB Project(ImagesEJB):

we will explain the EJB module in details containing the entity classes,the EJBS,and the presistence file:


Entity classes:
We have two entity classes for our two tables EmployeeEntity and ImageEntity for Employees and Images tables.they are in the“model.entities” package.  

ImageEntity:
 package model.entities;  
 import java.io.Serializable;  
 import javax.persistence.*;  
 /**  
  * The persistent class for the IMAGES database table.  
  *   
  */  
 @Entity  
 @Table(name = "IMAGES")  
 public class ImageEntity implements Serializable {  
      private static final long serialVersionUID = 1L;  
      @Id  
      @SequenceGenerator(name = "IMAGES_IMAGEID_GENERATOR", sequenceName = "IMAGES_SEQ")  
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "IMAGES_IMAGEID_GENERATOR")  
      @Column(name = "IMAGE_ID")  
      private Long imageId;  
      @Lob  
      @Column(name = "IMAGE")  
      private byte[] image;  
      @Column(name = "IMAGE_NAME")  
      private String imageName;  
      @Column(name = "IMAGE_TYPE")  
      private String imageType;  
      @OneToOne(fetch = FetchType.EAGER)  
      @JoinColumn(name = "ID_OF_EMPLOYEE", nullable = false, unique = true)  
      private EmployeeEntity emp;  
      public EmployeeEntity getEmp() {  
           return emp;  
      }  
      public void setEmp(EmployeeEntity emp) {  
           this.emp = emp;  
      }  
      public Long getImageId() {  
           return this.imageId;  
      }  
      public void setImageId(Long imageId) {  
           this.imageId = imageId;  
      }  
      public byte[] getImage() {  
           return this.image;  
      }  
      public void setImage(byte[] image) {  
           this.image = image;  
      }  
      public String getImageName() {  
           return this.imageName;  
      }  
      public void setImageName(String imageName) {  
           this.imageName = imageName;  
      }  
      public String getImageType() {  
           return this.imageType;  
      }  
      public void setImageType(String imageType) {  
           this.imageType = imageType;  
      }  
      @Override  
      public int hashCode() {  
           int hash = 0;  
           hash += (imageId != null ? imageId.hashCode() : 0);  
           return hash;  
      }  
      @Override  
      public boolean equals(Object object) {  
           // TODO: Warning - this method won't work in the case the id fields are  
           // not set  
           if (!(object instanceof ImageEntity)) {  
                return false;  
           }  
           ImageEntity other = (ImageEntity) object;  
           if ((this.imageId == null && other.imageId != null)  
                     || (this.imageId != null && !this.imageId.equals(other.imageId))) {  
                return false;  
           }  
           return true;  
      }  
      @Override  
      public String toString() {  
           return "model.entities.ImageEntity[ imageId=" + imageId + " ]";  
      }  
 }  
EmployeeEntity:
 package model.entities;  
 import java.io.Serializable;  
 import javax.persistence.*;  
 import java.math.BigDecimal;  
 import java.util.Date;  
 import java.util.List;  
 /**  
  * The persistent class for the EMPLOYEES database table.  
  *   
  */  
 @Entity  
 @Table(name = "EMPLOYEES")  
 public class EmployeeEntity implements Serializable {  
      private static final long serialVersionUID = 1L;  
      @Id  
      @SequenceGenerator(name = "EMPLOYEES_EMPLOYEEID_GENERATOR", sequenceName = "EMPLOYEES_SEQ")  
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "EMPLOYEES_EMPLOYEEID_GENERATOR")  
      @Column(name = "EMPLOYEE_ID")  
      private Long employeeId;  
      @Column(name = "COMMISSION_PCT")  
      private BigDecimal commissionPct;  
      @Column(name = "DEPARTMENT_ID")  
      private BigDecimal departmentId;  
      private String email;  
      @Column(name = "FIRST_NAME")  
      private String firstName;  
      @Temporal(TemporalType.DATE)  
      @Column(name = "HIRE_DATE")  
      private Date hireDate;  
      @Column(name = "JOB_ID")  
      private String jobId;  
      @Column(name = "LAST_NAME")  
      private String lastName;  
      @Column(name = "PHONE_NUMBER")  
      private String phoneNumber;  
      private BigDecimal salary;  
      // bi-directional many-to-one association to EmployeeEntity  
      @ManyToOne  
      @JoinColumn(name = "MANAGER_ID")  
      private EmployeeEntity employee;  
      // bi-directional many-to-one association to EmployeeEntity  
      @OneToMany(mappedBy = "employee")  
      private List<EmployeeEntity> employees;  
      // bi-directional one-to-one association to ImageEntity  
      @OneToOne(mappedBy = "emp")  
      private ImageEntity Image;  
      public ImageEntity getImage() {  
           return Image;  
      }  
      public void setImage(ImageEntity image) {  
           Image = image;  
      }  
      public EmployeeEntity() {  
      }  
      public Long getEmployeeId() {  
           return this.employeeId;  
      }  
      public void setEmployeeId(Long employeeId) {  
           this.employeeId = employeeId;  
      }  
      public BigDecimal getCommissionPct() {  
           return this.commissionPct;  
      }  
      public void setCommissionPct(BigDecimal commissionPct) {  
           this.commissionPct = commissionPct;  
      }  
      public BigDecimal getDepartmentId() {  
           return this.departmentId;  
      }  
      public void setDepartmentId(BigDecimal departmentId) {  
           this.departmentId = departmentId;  
      }  
      public String getEmail() {  
           return this.email;  
      }  
      public void setEmail(String email) {  
           this.email = email;  
      }  
      public String getFirstName() {  
           return this.firstName;  
      }  
      public void setFirstName(String firstName) {  
           this.firstName = firstName;  
      }  
      public Date getHireDate() {  
           return this.hireDate;  
      }  
      public void setHireDate(Date hireDate) {  
           this.hireDate = hireDate;  
      }  
      public String getJobId() {  
           return this.jobId;  
      }  
      public void setJobId(String jobId) {  
           this.jobId = jobId;  
      }  
      public String getLastName() {  
           return this.lastName;  
      }  
      public void setLastName(String lastName) {  
           this.lastName = lastName;  
      }  
      public String getPhoneNumber() {  
           return this.phoneNumber;  
      }  
      public void setPhoneNumber(String phoneNumber) {  
           this.phoneNumber = phoneNumber;  
      }  
      public BigDecimal getSalary() {  
           return this.salary;  
      }  
      public void setSalary(BigDecimal salary) {  
           this.salary = salary;  
      }  
      public EmployeeEntity getEmployee() {  
           return this.employee;  
      }  
      public void setEmployee(EmployeeEntity employee) {  
           this.employee = employee;  
      }  
      public List<EmployeeEntity> getEmployees() {  
           return this.employees;  
      }  
      public void setEmployees(List<EmployeeEntity> employees) {  
           this.employees = employees;  
      }  
 }  
About the above code:
The two entities are generated by eclipse as we explained earlier in the previous posts,but take care of the code in bold:

We use the sequence approach to generate the entity ID for our entities,The value sequenceName reflects the database sequence name.Note that we have two sequences for our two entities but we will use IMAGES_SEQ that we created earlier while inserting our images in the database.

The employee and image entities have a Bidirectional one to one relation.One Employee can have only one Image.The meaning of Bidirectional is that each side of association has a refer to the other and see it. If we have a fetched employee object we will be able to retrieve the corresponding image and Vice a versa if we have image object, we will be able to get the corresponding employee object .
    
For the Image Entity we have these lines of code:
  @OneToOne(fetch=FetchType.EAGER)  
  @JoinColumn(name="ID_OF_EMPLOYEE", nullable=false,unique=true)  
  private EmployeeEntity emp;  

@OneToOne: This annotation indicates to the JPA that there is a relationship between the two entities 
 Fetch: the default value is EAGER;this value means that every time you search in the database for an Employee, the Employee Image is search automatically.
@JoinColumn: This annotation will indicate to the JPA that the foreign key will be located in the Images database table, making the Image entity owner of the relationship.Being the relationship owner is nothing more than to have the foreign key in the database table
nullable: Whether the foreign key column is nullable. Default is true  
unique: Whether the property is a unique key. Defalut is false, hence we have explicitly made it true as one employee cannot have two images

For the EmployeeEntity:
  @OneToOne(mappedBy = "emp")   
   private ImageEntity Image;   

@OneToOne: the same annotation @OneToOne Image is used in the Employee entity.
 mappedBy :The parameter “mappedBy” was used in the @OneToOne.This parameter indicates that the entityImage is the owner of the relationship; the foreign key must exist inside the Images table, and not the Employees table. 


Business logic or EJBS:

1- Generic DAO:

The Generic DAO class is a generic class capable of being used with a number of different entities. A specific entity is assigned and retrieved using the Generic DAO 's constructor.It has CRUD methods  plus find method which returns a single object of entity after taking entity Id as an argument.
 package model.ejb;  
 import java.util.List;  
 import javax.persistence.EntityManager;  
 import javax.persistence.PersistenceContext;  
 import javax.persistence.criteria.CriteriaQuery;  
 public abstract class GenericDAO<T> {  
      private final static String UNIT_NAME = "ImagesPU";  
      @PersistenceContext(unitName = UNIT_NAME)  
      private EntityManager em;  
      private Class<T> entityClass;  
      public GenericDAO(Class<T> entityClass) {  
           this.entityClass = entityClass;  
      }  
      public void save(T entity) {  
           em.persist(entity);  
           em.flush();  
      }  
      public void update(T entity) {  
           em.merge(entity);  
      }  
      public T find(Long entityID) {  
           return em.find(entityClass, entityID);  
      }  
      @SuppressWarnings({ "unchecked", "rawtypes" })  
      public List<T> findAll() {  
           CriteriaQuery cq = em.getCriteriaBuilder().createQuery();  
           cq.select(cq.from(entityClass));  
           return em.createQuery(cq).getResultList();  
      }  
 }  
2-EmployeeBean:

Employee bean EJB class extends GenericDAO and has two methods.One to get all the Employees for the primfaces Datatable and other method to update the Employee Entity after uploading an Image for any Employee.
 package model.ejb;  
 import java.util.List;  
 import javax.ejb.LocalBean;  
 import javax.ejb.Stateless;  
 import model.entities.EmployeeEntity;  
 import model.entities.ImageEntity;  
 /**  
  * Session Bean implementation class EmployeeBean  
  */  
 @Stateless  
 @LocalBean  
 public class EmployeeBean extends GenericDAO<EmployeeEntity> {  
      public EmployeeBean() {  
           super(EmployeeEntity.class);  
      }  
      // get AllEmployees  
      public List<EmployeeEntity> findAll() {  
           return super.findAll();  
      }  
      // update EmployeeEntity after Adding an Image to Employee  
      public void AddImgtoEmployee(EmployeeEntity selectedEmployee,  
                ImageEntity image) {  
           selectedEmployee.setImage(image);  
           super.update(selectedEmployee);  
      }  
 }  
3-ImageBean:

Image Bean EJB class extends GenericDAO and also has two methods.one to save the uploading image in the database through super.save(Image)and the other takes the id of the image as a parameter and then showing it using our servlet class which we will create in the JSF project.
 package model.ejb;  
 import javax.ejb.LocalBean;  
 import javax.ejb.Stateless;  
 import model.entities.ImageEntity;  
 /**  
  * Session Bean implementation class ImageBean  
  */  
 @Stateless  
 @LocalBean  
 public class ImageBean extends GenericDAO<ImageEntity> {  
      public ImageBean() {  
           super(ImageEntity.class);  
      }  
      public void saveImage(ImageEntity Image) {  
           super.save(Image);  
      }  
      // Find Image by Its Id to show the Image Using Servlet  
      public ImageEntity findImage(Long ImageId) {  
           return super.find(ImageId);  
      }  
}
For the presisternce.xml I will not talk in details about it as we already do this in the previous posts but you should know that the name of the persistence unit we have specified is the same as in the PersistenceContext in the Generic DAO class and jdbc/hrConn is the name of our datasource which we create in glassfish in our first post from here to use it in all our applications. 
   
3-JSF  Project(ImagesWeb):

Our JSF project represents the interface or the web logic which depends on EJB project, call many methods from EJB beans and also has many business logic,managed beans,validators,and other codes.Let us explore it 



Java Resources:

com.mb package:

AbstractBacking:

This class is a utility class and represents the base for all our managed beans.See the code of the class when download the App.

EmployeeWeb:

EmployeesWeb is a viewScoped managedbean.As we said in our previous posts we are using @EJB annotations to inject the EJB inside of the MB.we have a method to load the employees for the datatable and another method to save the selected employee in the flash scope and then navigate away to the page where you upload a photo for him.
 package com.mb;  
 import java.io.Serializable;  
 import java.util.List;  
 import javax.ejb.EJB;  
 import javax.faces.bean.ManagedBean;  
 import javax.faces.bean.ViewScoped;  
 import model.ejb.EmployeeBean;  
 import model.entities.EmployeeEntity;  
 @ManagedBean  
 @ViewScoped  
 public class EmployeeWeb extends AbstractBacking implements Serializable {  
      /**  
       *   
       */  
      private static final long serialVersionUID = 1L;  
      @EJB  
      private EmployeeBean employeeBean;  
      private List<EmployeeEntity> employees;  
      private EmployeeEntity selectedEmployee;  
      public EmployeeEntity getSelectedEmployee() {  
           return selectedEmployee;  
      }  
      public void setSelectedEmployee(EmployeeEntity selectedEmployee) {  
           this.selectedEmployee = selectedEmployee;  
      }  
      private void loadEmployees() {  
           try {  
                employees = employeeBean.findAll();  
           } catch (Exception e) {  
                displayErrorMessageToUser("Error while processing getting Employees list");  
                e.printStackTrace();  
           }  
      }  
      public List<EmployeeEntity> getAllEmployees() {  
           if (employees == null) {  
                loadEmployees();  
           }  
           return employees;  
      }  
      /**  
       * ------ a method to navigate to EmpImage.xhtml after saving the Selected  
       * Employee in Flash scope to get his Image or upload one if he has not an  
       * Image -----  
       */  
      public String getEmployeeImage() {  
           getFlash().put("selectedEmployee", selectedEmployee);  
           return "/pages/EmpImage?faces-redirect=true";  
      }  
 }  
ImagesWeb:

The following managed bean has much logic and codes. In brief the managed bean do the following:

1- Restore the selected employee from flash
2-Insert the image with all its details in the database and display success or Error Messages to the user If some exception or Error happens. 
3-For loadImageForEmployee method I first want the user to select an employee then to navigate to the uploading page to upload a photo for him in other words I want to prevent direct access to the uploading page without selecting any employees so this method which we call in the preRenderView event will ensure that the selected employee is not null otherwise it will redirect the user to the employees page to select first an employee. 
 package com.mb;  
 import java.io.Serializable;  
 import javax.ejb.EJB;  
 import javax.faces.bean.ManagedBean;  
 import javax.faces.bean.ViewScoped;  
 import javax.faces.context.FacesContext;  
 import model.ejb.EmployeeBean;  
 import model.ejb.ImageBean;  
 import model.entities.EmployeeEntity;  
 import model.entities.ImageEntity;  
 import javax.faces.event.ComponentSystemEvent;  
 import org.apache.commons.io.FilenameUtils;  
 import org.primefaces.model.UploadedFile;  
 @ManagedBean  
 @ViewScoped  
 public class ImagesWeb extends AbstractBacking implements Serializable {  
           
      private static final long serialVersionUID = 1L;  
      private UploadedFile file;  
      @EJB  
      private ImageBean imageBean;  
      @EJB  
      private EmployeeBean employeeBean;  
      private EmployeeEntity SelectedEmployee;  
      public EmployeeEntity getSelectedEmployee() {  
           if (SelectedEmployee == null) {  
                SelectedEmployee = (EmployeeEntity) getFlash().get(  
                          "selectedEmployee");  
           }  
           return SelectedEmployee;  
      }  
      public void setSelectedEmployee(EmployeeEntity selectedEmployee) {  
           SelectedEmployee = selectedEmployee;  
      }  
      public UploadedFile getFile() {  
           return file;  
      }  
      public void setFile(UploadedFile file) {  
           this.file = file;  
      }  
      public void loadImageForEmployee(ComponentSystemEvent cse) {  
           if (null == getSelectedEmployee()) {  
                FacesContext  
                          .getCurrentInstance()  
                          .getApplication()  
                          .getNavigationHandler()  
                          .handleNavigation(FacesContext.getCurrentInstance(), null,  
                                    "/pages/Employees?faces-redirect=true");  
           }  
      }  
      public void add() {  
           try {  
                String fileName = FilenameUtils.getName(file.getFileName());  
                System.out.println(FilenameUtils.getExtension(fileName));  
                System.out.println(file.getFileName());  
                String contentType = FacesContext.getCurrentInstance()  
                          .getExternalContext().getMimeType(fileName);  
                byte[] bytes = file.getContents();  
                ImageEntity img = new ImageEntity();  
                img.setImageName(fileName);  
                img.setImage(bytes);  
                img.setImageType(contentType);  
                img.setEmp(SelectedEmployee);  
                imageBean.save(img);  
                employeeBean.AddImgtoEmployee(SelectedEmployee, img);  
                displayInfoMessageToUser(String.format(  
                          "File '%s' of type '%s' successfully uploaded!", fileName,  
                          contentType));  
           } catch (Exception e) {  
                displayErrorMessageToUser("File upload failed with error.");  
                // Always log stacktraces (with a real logger).  
                e.printStackTrace();  
           }  
      }  
 }  
If you do not know what is the purpose of DataTableControllPagination managed bean or the filter see the previous post from here to know this. 

com.servlet package:

ImageServlet:

We need to load our image from the database and display it to the user,this is possible with a servlet.The code is clear.The servlet gets the ImageId from the request,call find by Id method to get the ImageEntity by its ID,prepare streams,open streams and write file contents to the response 
 package com.servlet;  
 import java.io.IOException;  
 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;  
 import java.io.Closeable;  
 import model.ejb.ImageBean;  
 import model.entities.ImageEntity;  
 import java.io.BufferedInputStream;  
 import java.io.BufferedOutputStream;  
 import java.io.ByteArrayInputStream;  
 /**  
  * Servlet implementation class ImageServlet  
  */  
 @WebServlet("/ImageServlet")  
 public class ImageServlet extends HttpServlet {  
      @EJB  
      private ImageBean imageBean;  
      private static final long serialVersionUID = 1L;  
      private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.  
      protected void doGet(HttpServletRequest req, HttpServletResponse res)  
                throws ServletException, IOException {  
           String imageId = req.getParameter("ImageId");  
           if (imageId == null) {  
                // Do your thing if the ID is not supplied to the request.  
                return;  
           }  
           // Lookup Image by ImageId in database.  
           ImageEntity Image = imageBean.find(Long.parseLong(imageId));  
           if (Image == null) {  
                return;  
           }  
           // Init servlet response.  
           res.reset();  
           res.setBufferSize(DEFAULT_BUFFER_SIZE);  
           res.setContentType(Image.getImageType());  
           res.setHeader("Content-Length", String.valueOf(Image.getImage().length));  
           res.setHeader("Content-Disposition",  
                     "attachment; filename=\"" + Image.getImageName() + "\"");  
           // Prepare streams.  
           BufferedInputStream input = null;  
           BufferedOutputStream output = null;  
           try {  
                // Open streams.  
                input = new BufferedInputStream(new ByteArrayInputStream(  
                          Image.getImage()), DEFAULT_BUFFER_SIZE);  
                output = new BufferedOutputStream(res.getOutputStream(),  
                          DEFAULT_BUFFER_SIZE);  
                // Write file contents to response.  
                byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];  
                int length;  
                while ((length = input.read(buffer)) > 0) {  
                     output.write(buffer, 0, length);  
                }  
           } finally {  
                // Gently close streams.  
                close(output);  
                close(input);  
           }  
      }  
      private static void close(Closeable resource) {  
           if (resource != null) {  
                try {  
                     resource.close();  
                } catch (IOException e) {  
                     // Do your thing with the exception. Print it, log it or mail it  
                     e.printStackTrace();  
                }  
           }  
      }  
 }  
Validate the size and type of Image before Uploading:

In our uploading process we use <p:fileUpload> in simple mode.I do not use Advanced mode because of its incompatibility for all browsers,but the client side facilities and validations are limited in this mode so we need another method to validate image type and size as the application will only permit jpg/jpeg,png and gif  images to be upoaded with a maximum size of 10mb. How we can achieve this?To do this we use client and server side validations

1-client side validation:
 <p:fileUpload mode="simple" styleClass="imagesOnlyMax10MB"/>  
The JS Function(using jQuery from PrimeFaces):
 $("input[type=file].imagesOnlyMax10MB").attr("accept", "image/*").on("change", function() {  
   var max = 10 * 1024 * 1024; // 10MB  
   if (this.files && this.files[0].size > max) {  
     alert("File too large."); // Do your thing to handle the error.  
     this.value = null; // Clears the field.  
   }  
 });  
2-server side validation:

the client side validation will work like a charm in web browsers that support the new HTML5 file API such as Firefox and chrome not for IE also the best practice is always, always validate server-side.This will be more secure in case your client-side validation is bypassed by the end user.For server side validation we use the following validator:
 package com.validator;  
 import javax.faces.application.FacesMessage;  
 import javax.faces.component.UIComponent;  
 import javax.faces.context.FacesContext;  
 import javax.faces.validator.FacesValidator;  
 import javax.faces.validator.Validator;  
 import javax.faces.validator.ValidatorException;  
 import org.apache.commons.io.FilenameUtils;  
 import org.primefaces.model.DefaultUploadedFile;  
 @FacesValidator(value = "fileValidator")  
 public class UploadValidator implements Validator {  
      private static final String[] ALLowed_Extensions = { "jpg", "jpeg", "gif",  
                "png" };  
      private static final long MAX_FILE_SIZE = 10485760L; // 10MB.  
      @Override  
      public void validate(FacesContext context, UIComponent component,  
                Object value) throws ValidatorException {  
           DefaultUploadedFile file = (DefaultUploadedFile) value;  
           if (file == null) {  
                return;  
           }  
           if (file.getSize() > MAX_FILE_SIZE) {  
                throw new ValidatorException(new FacesMessage(  
                          FacesMessage.SEVERITY_ERROR,  
                          "File exceeds maximum permitted size of 10MB", null));  
           }  
           Boolean AllowedExtension = isExtensionAllowed(FilenameUtils  
                     .getExtension(file.getFileName()));  
           /** ------ [ If extesion is not Allowed ] ----- */  
           if (!AllowedExtension) {  
                throw new ValidatorException(new FacesMessage(  
                          FacesMessage.SEVERITY_ERROR, "Image Extension not Allowed",  
                          null));  
           }  
      }  
      private static Boolean isExtensionAllowed(String ImageExt) {  
           for (int i = 0; i < ALLowed_Extensions.length; i++) {  
                if (ImageExt.toLowerCase().equals(ALLowed_Extensions[i])) {  
                     return Boolean.TRUE;  
                }  
           }  
           return Boolean.FALSE;  
      }  
 }  
The web pages:


We have two pages in the webcontent/pages folder:

Employees page :

This page has a primfaces datatable that lists all the employees of HR. Notice that we are passing to the EmployeeWeb MB the selected employee through the tag "f:setPropertyActionListeneralso notice the action method of p:commandLink Which navigate to the uploading page after saving the selected employee in the flash scope as we said ealier.
 <!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"  
      xmlns:p="http://primefaces.org/ui"  
      xmlns:f="http://java.sun.com/jsf/core">  
 <h:head>  
      <title>dataTable page</title>  
      <h:outputStylesheet name="style/mystyle.css" />  
 </h:head>  
 <h:body>  
      <p:growl />  
      <p:panel style="width:100%;text-align:center" header="Employees Table" />  
      <p:layoutUnit position="center">  
           <h:form id="table" prependId="false">  
                <p:dataTable id="employeesTable" value="#{employeeWeb.allEmployees}"  
                     var="emp" emptyMessage="NO Employees" paginator="true"  
                     paginatorAlwaysVisible="false" rows="10"  
                     style="width: 100%;height: 150px"  
                     paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"  
                     first="#{dataTableControllPagination.first}">  
                     <p:ajax event="page"  
                          listener="#{dataTableControllPagination.onPageChange}" />  
                     <p:column id="EmployeeId" headerText="EmployeeId">  
                          <h:outputText value="#{emp.employeeId}" />  
                     </p:column>  
                     <p:column id="LastName" headerText="lastName">  
                          <h:outputText value="#{emp.lastName}" />  
                     </p:column>  
                     <p:column id="Salary" headerText="salary">  
                          <h:outputText value="#{emp.salary}" />  
                     </p:column>  
                     <p:column id="Manager" headerText="Manager">  
                          <h:outputText value="#{emp.employee.lastName}" />  
                     </p:column>  
                     <p:column>  
                          <p:commandLink action="#{employeeWeb.getEmployeeImage()}"  
                               ajax="false">  
                               <p:graphicImage name="img/picture.png" />  
                               <f:setPropertyActionListener  
                                    target="#{employeeWeb.selectedEmployee}" value="#{emp}" />  
                          </p:commandLink>  
                     </p:column>  
                </p:dataTable>  
           </h:form>  
      </p:layoutUnit>  
 </h:body>  
 </html>  
EmpImage.xhtml:

Our uploading page where you can upload an image for any employee you select if this employee has not an image or the page will display the employee's image loaded from database 
 <!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"  
      xmlns:p="http://primefaces.org/ui"  
      xmlns:f="http://java.sun.com/jsf/core">  
 <f:event listener="#{imagesWeb.loadImageForEmployee}"  
      type="preRenderView" />  
 <h:head>  
 </h:head>  
 <h:body>  
      <p:growl life="5000" autoUpdate="true" />  
      <p:panel style="width:100%;border:0 ;text-align:center"  
           header="Employee Image">  
      </p:panel>  
      <h:form id="uploadForm" enctype="multipart/form-data">  
           <h:panelGroup columns="1"  
                rendered="#{imagesWeb.selectedEmployee.image==null}">  
                <p:outputLabel for="file"  
                     value="Select Image for #{imagesWeb.selectedEmployee.lastName}" />  
                <p:fileUpload id="file" value="#{imagesWeb.file}" required="true"  
                     mode="simple" validator="fileValidator"  
                     styleClass="imagesOnlyMax10MB" />  
                <p:spacer width="10px" />  
                <p:commandButton value="Submit" ajax="false" id="upload"  
                     action="#{imagesWeb.add}" />  
                <p:spacer width="50px" />  
                <p:separator />  
           </h:panelGroup>  
           <p:panelGrid columns="2" styleClass="panelGridnoborder">  
                <h:outputText value="Name" />  
                <h:outputText  
                     value="#{imagesWeb.selectedEmployee.firstName} #{imagesWeb.selectedEmployee.lastName}"  
                     title="Name" />  
                <h:outputText value="Photo" />  
                <p:graphicImage name="img/no_image.jpg"  
                     rendered="#{imagesWeb.selectedEmployee.image==null}" />  
                <p:graphicImage  
                     value="/ImageServlet?ImageId=#{imagesWeb.selectedEmployee.image.imageId}"  
                     rendered="#{imagesWeb.selectedEmployee.image!=null}" />  
           </p:panelGrid>  
           <h:button outcome="Employees" value="Employees Table" />  
      </h:form>  
      <h:outputStylesheet name="style/mystyle.css" />  
      <h:outputScript library="javascript" name="jscode.js" />  
 </h:body>  
 </html>  
Take care of  the following points in our web page:

1-preRenderView event which call loadImageForEmployee to ensure that the user select an Employee otherwise it will redirect him to the Employees datatable page
2-Primfaces growl to display FacesMessages instead of h:messages
3-<h:panelGroup> to wrap the primfaces fileupload and notice the rendered attribute of the panel group to be rendered only if this employee has not any image in the database.
4-<p:fileUpload> for uploading files.Its mode is simple as we said ealier and notice the validator and styleClass attributes.
5-inside the panel grid we have two images no image available image when the employee has not an image and a dynamic image which has its value from the servlet to show the employee's image loaded from database if this employee has one
 <p:graphicImage name="img/no_image.jpg" rendered="#{imagesWeb.selectedEmployee.image==null}" /> 
      <p:graphicImage value="/ImageServlet?ImageId=#{imagesWeb.selectedEmployee.image.imageId}"  
                     rendered="#{imagesWeb.selectedEmployee.image!=null}" />  
The libraries:

For the uploading process to work we have two Jar files in the WEB-INF/lib folder commons-fileupload.jar, commons-io-1.4.jar in Addition to the primefaces-3.5.jar file.

The Web.xml file:

We should declare the PrimeFaces FileUpload filter in web.xml file so the web.xml should finally look like that:
 <?xml version="1.0" encoding="UTF-8"?>  
 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  
  <display-name>ImagesWeb</display-name>  
  <welcome-file-list>  
   <welcome-file>pages/Employees.xhtml</welcome-file>  
  </welcome-file-list>  
  <servlet>  
   <servlet-name>Faces Servlet</servlet-name>  
   <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>  
   <load-on-startup>1</load-on-startup>  
  </servlet>  
  <servlet-mapping>  
   <servlet-name>Faces Servlet</servlet-name>  
   <url-pattern>*.xhtml</url-pattern>  
  </servlet-mapping>  
   <filter>  
     <filter-name>PrimeFaces FileUpload Filter</filter-name>  
     <filter-class>org.primefaces.webapp.filter.FileUploadFilter  
     </filter-class>  
     <init-param>  
       <param-name>thresholdSize</param-name>  
       <param-value>1024</param-value> <!-- 1 Mb -->  
     </init-param>  
   </filter>  
   <filter-mapping>  
     <filter-name>PrimeFaces FileUpload Filter</filter-name>  
     <servlet-name>Faces Servlet</servlet-name>  
   </filter-mapping>   
 </web-app>  
Running the Application:

Now finally we reach to the most important step.It is running our application in glassfish application server.How can we do this?

First:: use the DML scripts in the beginning of our post to create the Images table and sequence in hr schema of your oracle database.
Second: create jdbc/hrConn Datasource in your glassfish server as we said in our first post preparing your Environment from here
Third: download the application from here, open it in your eclipse,deploy it in your glassfish by selecting the Ear file and Run as->Run on server ->select your glassfish server and then ok as we explain by pictures in creating Master_detail post from here (see the last section)
Fourth: To access our Application use the URL: http://localhost:8080/ImagesWeb/ (note that 8080 is the port of my Glassfish server you may use a different port depending on the configuration of your glassfish)

You will see a primfaces datatable that lists all the employees of hr schema, select any employee and press the Image button to navigate to the uploading page


As we see from the previous picture we select Adam Vollman (EmployeeId 123) and go to the uploading page, because he has not any image in the database we will be asked to upload one for him and in the other section of the page we will see his complete name and no Image available picture


Click browse button to select an image and note that the File upload window will accept only Image Files as we explained earlier


select an image and click submit button, after the image is validated also from the server side,the p:fileUpload  will disappear and you will see the image loaded from the database



 If you navigate back to the Employees page and select the same employee again then go to the uploading  page you will see his complete name, photo and you can not upload any other image for him because he has already one in the database.

If you have any questions please post it below 

coming soon:

cascading primfaces selectOneMenu using EJB3 and JSF2 framework.

See you soon and until then happy JSF Developing.