1

I am using primfaces 3.5 version to show images from my database in datatable, but unfortunately instead of actual images "image" is getting written in column, here is my xhtml file

<?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"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">
    <body>

        <ui:composition template="./template.xhtml">    
            <ui:define name="top">    
            </ui:define>    
            <ui:define name="left">
                left
            </ui:define>    
            <ui:define name="content">
                <h:form id="form1">      
                    <p:panel id="panel" header="New Category">      
                        <p:messages id="msgs1"/>      
                        <h:panelGrid columns="3">  
                            <h:outputLabel for="categoryName" value="Category Name: *" />  
                            <p:inputText id="categoryname" value="#{categoryBean.categoryName}" required="true" label="Categoryname">  
                                <f:validateLength minimum="2" />  
                            </p:inputText> 

                            <p:message for="categoryname" display="icon"/>     
                            <h:outputLabel value="Upload Image" />
                            <p:fileUpload fileUploadListener="#{categoryBean.upload}"
                                          allowTypes="/(\.|\/)(gif|jpe?g|png)$/" sizeLimit="100000" description="Select Images"/>        
                        </h:panelGrid>      
                        <p:commandButton id="btn" value="Save"  update=":form:count" />  
                    </p:panel>      
                </h:form>  

                <h:form id="form">    
                    <p:spacer height="20px"></p:spacer>    
                    <p:dataTable id="count" var="category"
                                 value="#{categoryBean.categories}" paginator="true" rows="7">    
                        <f:facet name="header">  
                            Available Categories  
                        </f:facet>

                        <p:column headerText="Category ID" style="width:4%">
                            <h:outputText value="#{category.idCat}" />
                        </p:column>

                        <p:column headerText="Category Name" style="width:24%">
                            <h:outputText value="#{category.categoryName}" />
                        </p:column>

                        <p:column headerText="Category Image" style="width:24%">
                            <p:graphicImage   alt="image"  value="#{category.categoryimg}" cache="false"  >

                            </p:graphicImage>
                    </p:column>

                    <p:column style="width:4%">

                        <p:commandButton value="Delete" action="#{categoryBean.deleteAction(category)}"  update=":form:count"/>

                    </p:column>    
                    </p:dataTable>    
                </h:form>
            </ui:define>

            <ui:define name="bottom">    
            </ui:define>    
        </ui:composition>    
    </body>
</html>

here is my managed bean :

package com.app.beans;

/**
 *
 * @author 
 */
@ManagedBean
@RequestScoped
public class CategoryBean implements Serializable{
   public  long idCat;
   public  String categoryName;
   public List<Category> categories;
   public ItemController itemController;
   byte[] data;
   private StreamedContent dbImage;

    public StreamedContent getDbImage() {
        return dbImage;
    }

    public void setDbImage(StreamedContent dbImage) {
        this.dbImage = dbImage;
    }

   public StreamedContent getImage(Category cat)throws IOException{
       FacesContext context = FacesContext.getCurrentInstance();
       System.out.println("int get images category id is: "+cat.getCategoryName());
    if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
        // So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
        System.out.println("So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.");
        return new DefaultStreamedContent();
    }else{
        System.out.println("in actual image content");
        dbImage= new DefaultStreamedContent(new ByteArrayInputStream(itemController.getImageByName(cat.getCategoryName())), "image/png");
        return dbImage;
    }
   }


    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;

        Category c = new Category();
        c.setCategoryName(categoryName);
        int status = itemController.setCategory(c);
        if(status == 1){
                categories.add(c);
        }
    }

    @PostConstruct
    public void init(){
        categories = new ArrayList<Category>();
        itemController = new ItemController();
        categories = itemController.getAllCategories();
    }

    public long getIdCat() {
        return idCat;
    }

    public void setIdCat(long idCat) {
        this.idCat = idCat;
    }



    public List<Category> getCategories() {
        return categories;
    }

    public void setCategories(List<Category> categories) {
        this.categories = categories;
    }



    /**
     * Creates a new instance of CategoryBean
     */
    public CategoryBean() {

    }

        public String deleteAction(Category c) {

        System.out.println("from deleteAction"+c.getCategoryName());
        int status = itemController.deleteCategory(c.getCategoryName());
        if(status == 1){
            categories.remove(c);
        }
        return null;
    }

        public void upload(FileUploadEvent event) {
        FacesMessage msg = new FacesMessage("Success! ", event.getFile().getFileName() + " is uploaded.");
        FacesContext.getCurrentInstance().addMessage(null, msg);
        // Do what you want with the file        
        System.out.println("From Upload" + event.getFile().getFileName());

        int nRead;
        data = new byte[16384];
        InputStream is = null;
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        try {
            is = event.getFile().getInputstream();
             while ((nRead = is.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, nRead);
             }
              buffer.flush();
        } catch (IOException ex) {
            Logger.getLogger(UpdateItem.class.getName()).log(Level.SEVERE, null, ex);
        }



    }
}

I am getting images corresponding to category name, that is comming in log, I am trying to understand why else part of my getImage function in not getting called
and this is the log getting generated :

WARNING: JSF1091: No mime type could be found for file dynamiccontent.  To resolve this, add a mime-type mapping to the applications web.xml.
Jun 07, 2013 11:14:41 PM com.sun.faces.context.ExternalContextImpl getMimeType
WARNING: JSF1091: No mime type could be found for file dynamiccontent.  To resolve this, add a mime-type mapping to the applications web.xml.
int get images category id is: xyz
So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
int get images category id is: x1
So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
int get images category id is: x2
So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
int get images category id is: Main Course
So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
int get images category id is: Drinks
So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
Jun 07, 2013 11:14:41 PM org.primefaces.application.PrimeResourceHandler handleResourceRequest
SEVERE: Error in streaming dynamic resource. java.lang.NullPointerException
Jun 07, 2013 11:14:41 PM org.primefaces.application.PrimeResourceHandler handleResourceRequest
SEVERE: Error in streaming dynamic resource. java.lang.NullPointerException
Jun 07, 2013 11:14:41 PM org.primefaces.application.PrimeResourceHandler handleResourceRequest
SEVERE: Error in streaming dynamic resource. java.lang.NullPointerException
Jun 07, 2013 11:14:41 PM org.primefaces.application.PrimeResourceHandler handleResourceRequest
SEVERE: Error in streaming dynamic resource. java.lang.NullPointerException
Jun 07, 2013 11:14:41 PM org.primefaces.application.PrimeResourceHandler handleResourceRequest
SEVERE: Error in streaming dynamic resource. java.lang.NullPointerException
Jun 07, 2013 11:14:42 PM org.primefaces.application.PrimeResourceHandler handleResourceRequest
SEVERE: Error in streaming dynamic resource. Expression cannot be null
Jun 07, 2013 11:14:42 PM org.primefaces.application.PrimeResourceHandler handleResourceRequest
SEVERE: Error in streaming dynamic resource. Expression cannot be null

When commented if else clause, it throws following error:

    SEVERE: Error Rendering View[/categoryUpdate.xhtml]
java.lang.NullPointerException
    at org.primefaces.component.graphicimage.GraphicImageRenderer.getImageSrc(GraphicImageRenderer.java:110)
    at org.primefaces.component.graphicimage.GraphicImageRenderer.encodeEnd(GraphicImageRenderer.java:46)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1763)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
    at org.primefaces.component.datatable.DataTableRenderer.encodeRegularCell(DataTableRenderer.java:741)
    at org.primefaces.component.datatable.DataTableRenderer.encodeRow(DataTableRenderer.java:693)
suspectus
  • 16,548
  • 8
  • 49
  • 57
focode
  • 648
  • 1
  • 16
  • 39
  • That BalusC's solution is a kind of hack to avoid the problem which supposes having two different http requests, calling the getter method twice. You seem to have only a request, have you tried removing the `if/else` block and executing only the second code block? – Aritz Jun 08 '13 at 08:37
  • I commented the if else part and executed it throws error, i have mentioned the error above – focode Jun 08 '13 at 10:19
  • Is the `new ByteArrayInputStream(itemController.getImageByName(cat.getCategoryName())` generating a valid input stream? I guess it doesn't. Check what your `itemController.getImageByName` is returning. – Aritz Jun 08 '13 at 10:24
  • should it return anything other than byte array ? – focode Jun 08 '13 at 14:22

1 Answers1

4

There are 2 mistakes in your approach so far:

  1. You must use <f:param> inside <p:graphicImage> to pass image ID. You cannot use EL 2.2 method argument passing in <p:graphicImage value>. The image is requested by a completely separate HTTP request. The EL 2.2 method argument passing is only used during generating HTML output, when the URL needs to be generated for <img src>. However that URL in turn must also uniquely identify the image and that can only be done with <f:param>.

  2. Not a technical problem, but more a design problem: you should put the image streamer in an entirely separate application scoped bean and not mingle it with "regular" managed bean code. This way the image streamer is reusable and you can clearly separate the concerns which makes the code better understandable and maintainable.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555