how to display images in dataTable using p:graphicImage in Primefaces

In this tutorial, let us see how to use p:graphicImage within dataTable tag in Primefaces. For example, let us display a list of products with images from a database. You can also visit my earlier tutorial for displaying dynamic images using p:graphicImage tag. 

Now let us see the complete code for displaying list of products with images using p:dataTable tag in primefaces.  Let us start with JSF code using p:dataTable and p:graphicImage

JSF Page (productList.xhtml)
<?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:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:p="http://primefaces.org/ui">
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
	<title>Example of using p:graphicImage and p:dataTable in JSF
		Primefaces</title>
</h:head>
<h:body>
	<h3>List of Products with Image using p:graphicImage and
		p:dataTable</h3>
	<h:form id="productListForm" prependId="false">

		<p:outputPanel id="testContainer">

			<p:dataTable id="docId" var="row" value="#{productBean.productList}"
				editable="false" widgetVar="documentTable">

				<p:column headerText="Product Id" style="width:10%">
					<h:outputText value="#{row.productId}" title="Id" />
				</p:column>

				<p:column headerText="Name" style="width:10%">
					<h:outputText value="#{row.productName}" title="Name" />
				</p:column>

				<p:column headerText="Image" style="width:30%">
					<p:graphicImage value="#{productBean.productImage}">
						<f:param name="pid" value="#{row.productId}" />
					</p:graphicImage>
				</p:column>
			</p:dataTable>
		</p:outputPanel>

	</h:form>

</h:body>
</html>

In the above JSF code, productId is passed as parameter to retrieve the corresponding product image from the database.

Now let us write managed bean code associated with the above JSF page

Product.java
package net.javaonline.jsf.primefaces.graphicimage.controller;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;

import net.javaonline.jsf.primefaces.graphicimage.dao.ProductImageDAO;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

@ManagedBean(name = "productBean")
@RequestScoped
public class Product implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private String productId;
	private String productName;
	private StreamedContent productImage;
	private List<Product> productList;


	public void setProductImage(StreamedContent productImage) {
		this.productImage = productImage;
	}

	public void setProductList(List<Product> productList) {
		this.productList = productList;
	}

	public List<Product> getProductList() throws IOException, SQLException {

		return new ProductImageDAO().getProductDetails();
	}

	public String getProductId() {
		return productId;
	}

	public void setProductId(String productId) {
		this.productId = productId;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	public StreamedContent getProductImage() throws IOException, SQLException {

		FacesContext context = FacesContext.getCurrentInstance();

		if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
			return new DefaultStreamedContent();
		}

		else {

			String id = context.getExternalContext().getRequestParameterMap()
					.get("pid");

			byte[] image = new ProductImageDAO().getProductImage(id);

			return new DefaultStreamedContent(new ByteArrayInputStream(image));

		}
	}

}

The above getter method getProductImage() is called twice by the tag <p:graphicImage> when the JSF page is invoked. First time simply DefaultStreamedContent()  is returned so that the URL for the <img>  tag is generated (If part is executed). Second time actual image is returned and rendered (else part is executed).

DAO code to retrieve binary data from database:
ProductImageDAO.java
package net.javaonline.jsf.primefaces.graphicimage.dao;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.context.FacesContext;

import net.javaonline.jsf.primefaces.graphicimage.controller.Product;

import org.primefaces.model.DefaultStreamedContent;

public class ProductImageDAO {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public byte[] getProductImage(String productId) throws IOException,
			SQLException {
		Connection con = null;
		PreparedStatement stmt = null;
		byte[] productImage = null;

		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection(
					"jdbc:mysql://localhost:3306/test", "root", "*****");
		} catch (Exception e) {
			System.out.println(e);
			System.exit(0);
		}

		stmt = con.prepareStatement("select * from product where productId=?");
		stmt.setString(1, productId);
		ResultSet rs = stmt.executeQuery();

		while (rs.next()) {
			productImage = rs.getBytes("productImage");
		}

		rs.close();
		con.close();

		return productImage;
	}

public List getProductDetails() throws IOException, SQLException {
 List<Product> productList = new ArrayList<Product>();

 Connection con = null;
 Statement stmt = null;

 try {
 Class.forName("com.mysql.jdbc.Driver");
 con = DriverManager.getConnection(
 "jdbc:mysql://localhost:3306/test", "root", "******");
 } catch (Exception e) {
 System.out.println(e);
 System.exit(0);
 }

 stmt = con.createStatement();
 ResultSet rs = stmt.executeQuery("select * from product");

 Product product;

 while (rs.next()) {

 product = new Product();

 String productId = rs.getString("productId");

 product.setProductId(productId.trim());
 product.setProductName(rs.getString("productName"));
 productList.add(product);
 }

 rs.close();
 con.close();
 return productList;
 }

}
DDL to create table structue used in this example:

CREATE TABLE Product
(
productId varchar(10) NOT NULL, productName varchar(100) NOT NULL,
productImage mediumblob, PRIMARY KEY ( productId )
);

Now insert product details with image using the below DML

insert into product values (‘I1’, ‘Samsung Tv’, LOAD_FILE(‘c:/temp/testimages/samsungtv.jpg’));

insert into product values (‘I2’, ‘SONY LED TV’, LOAD_FILE(‘c:/temp/testimages/sonytv.jpg’));

Note: Place the image files to be uploaded in the folder c:/temp/testimages

Now Two records are inserted.

Running the application will result the below output

graphicImage and datatable

Technology used in the project:

JSF 2.2

Primefaces 5.2

Eclipse

Apache Tomcat V7.0

MySQL

Java 1.7

 

Reference:  PrimeFaces GraphicImage and DataTable

Leave a Reply