Display dynamic image from database with p:graphicImage and StreamedContent












45















I'm trying to display image bytes which is saved in database as a StreamedContent in the <p:graphicImage> as follows:



<p:graphicImage  value="#{item.imageF}" width="50"  id="grpImage" height="80"/>


private StreamedContent content; // getter and setter

public StreamedContent getImageF() {

if (student.getImage() != null) {
InputStream is = new ByteArrayInputStream(student.getImage());
System.out.println("Byte :"+student.getImage());
content = new DefaultStreamedContent(is, "", student.getStuID());
System.out.println("ddd ------------------------------- " + content);
return content;
}

return content;
}


This returns a blank image. How is this caused and how can I solve it?



The stdout prints the following:



INFO: Byte :[B@a2fb48
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@b0887b
INFO: Byte :[B@a2fb48
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1d06a92
INFO: Byte :[B@d52f0b
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@39a60
INFO: Byte :[B@d52f0b
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@8c3daa
INFO: Byte :[B@124728a
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1dbe05b
INFO: Byte :[B@124728a
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@66a266
INFO: Byte :[B@a2fb48
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1293976
INFO: Byte :[B@a2fb48
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@17b7399
INFO: Byte :[B@d52f0b
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1e245a5
INFO: Byte :[B@d52f0b
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@4a7153
INFO: Byte :[B@124728a
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1561bfd
INFO: Byte :[B@124728a
INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@47a8c2









share|improve this question





























    45















    I'm trying to display image bytes which is saved in database as a StreamedContent in the <p:graphicImage> as follows:



    <p:graphicImage  value="#{item.imageF}" width="50"  id="grpImage" height="80"/>


    private StreamedContent content; // getter and setter

    public StreamedContent getImageF() {

    if (student.getImage() != null) {
    InputStream is = new ByteArrayInputStream(student.getImage());
    System.out.println("Byte :"+student.getImage());
    content = new DefaultStreamedContent(is, "", student.getStuID());
    System.out.println("ddd ------------------------------- " + content);
    return content;
    }

    return content;
    }


    This returns a blank image. How is this caused and how can I solve it?



    The stdout prints the following:



    INFO: Byte :[B@a2fb48
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@b0887b
    INFO: Byte :[B@a2fb48
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1d06a92
    INFO: Byte :[B@d52f0b
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@39a60
    INFO: Byte :[B@d52f0b
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@8c3daa
    INFO: Byte :[B@124728a
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1dbe05b
    INFO: Byte :[B@124728a
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@66a266
    INFO: Byte :[B@a2fb48
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1293976
    INFO: Byte :[B@a2fb48
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@17b7399
    INFO: Byte :[B@d52f0b
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1e245a5
    INFO: Byte :[B@d52f0b
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@4a7153
    INFO: Byte :[B@124728a
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1561bfd
    INFO: Byte :[B@124728a
    INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@47a8c2









    share|improve this question



























      45












      45








      45


      26






      I'm trying to display image bytes which is saved in database as a StreamedContent in the <p:graphicImage> as follows:



      <p:graphicImage  value="#{item.imageF}" width="50"  id="grpImage" height="80"/>


      private StreamedContent content; // getter and setter

      public StreamedContent getImageF() {

      if (student.getImage() != null) {
      InputStream is = new ByteArrayInputStream(student.getImage());
      System.out.println("Byte :"+student.getImage());
      content = new DefaultStreamedContent(is, "", student.getStuID());
      System.out.println("ddd ------------------------------- " + content);
      return content;
      }

      return content;
      }


      This returns a blank image. How is this caused and how can I solve it?



      The stdout prints the following:



      INFO: Byte :[B@a2fb48
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@b0887b
      INFO: Byte :[B@a2fb48
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1d06a92
      INFO: Byte :[B@d52f0b
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@39a60
      INFO: Byte :[B@d52f0b
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@8c3daa
      INFO: Byte :[B@124728a
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1dbe05b
      INFO: Byte :[B@124728a
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@66a266
      INFO: Byte :[B@a2fb48
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1293976
      INFO: Byte :[B@a2fb48
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@17b7399
      INFO: Byte :[B@d52f0b
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1e245a5
      INFO: Byte :[B@d52f0b
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@4a7153
      INFO: Byte :[B@124728a
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1561bfd
      INFO: Byte :[B@124728a
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@47a8c2









      share|improve this question
















      I'm trying to display image bytes which is saved in database as a StreamedContent in the <p:graphicImage> as follows:



      <p:graphicImage  value="#{item.imageF}" width="50"  id="grpImage" height="80"/>


      private StreamedContent content; // getter and setter

      public StreamedContent getImageF() {

      if (student.getImage() != null) {
      InputStream is = new ByteArrayInputStream(student.getImage());
      System.out.println("Byte :"+student.getImage());
      content = new DefaultStreamedContent(is, "", student.getStuID());
      System.out.println("ddd ------------------------------- " + content);
      return content;
      }

      return content;
      }


      This returns a blank image. How is this caused and how can I solve it?



      The stdout prints the following:



      INFO: Byte :[B@a2fb48
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@b0887b
      INFO: Byte :[B@a2fb48
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1d06a92
      INFO: Byte :[B@d52f0b
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@39a60
      INFO: Byte :[B@d52f0b
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@8c3daa
      INFO: Byte :[B@124728a
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1dbe05b
      INFO: Byte :[B@124728a
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@66a266
      INFO: Byte :[B@a2fb48
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1293976
      INFO: Byte :[B@a2fb48
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@17b7399
      INFO: Byte :[B@d52f0b
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1e245a5
      INFO: Byte :[B@d52f0b
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@4a7153
      INFO: Byte :[B@124728a
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@1561bfd
      INFO: Byte :[B@124728a
      INFO: ddd ------------------------------- org.primefaces.model.DefaultStreamedContent@47a8c2






      database image jsf jsf-2 primefaces






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 2 '15 at 8:11









      BalusC

      847k29831423217




      847k29831423217










      asked Nov 21 '11 at 4:36









      minhltntminhltnt

      226144




      226144
























          4 Answers
          4






          active

          oldest

          votes


















          89














          The <p:graphicImage> requires a special getter method. It will namely be invoked twice per generated image, each in a completely different HTTP request.



          The first HTTP request, which has requested the HTML result of a JSF page, will invoke the getter for the first time in order to generate the HTML <img> element with the right unique and auto-generated URL in the src attribute which contains information about which bean and getter exactly should be invoked whenever the webbrowser is about to request the image. Note that the getter does at this moment not need to return the image's contents. It would not be used in any way as that's not how HTML works (images are not "inlined" in HTML output, but they are instead requested separately).



          Once the webbrowser retrieves the HTML result as HTTP response, it will parse the HTML source in order to present the result visually to the enduser. Once the webbrowser encounters an <img> element during parsing the HTML source, then it will send a brand new HTTP request on the URL as specified in its src attribute in order to download the content of that image and embed it in the visual presentation. This will invoke the getter method for the second time which in turn should return the actual image content.



          In your particular case PrimeFaces was apparently either unable to identify and invoke the getter in order to retrieve the actual image content, or the getter didn't return the expected image content. The usage of #{item} variable name and the lot of calls in the log suggests that you were using it in an <ui:repeat> or a <h:dataTable>. Most likely the backing bean is request scoped and the datamodel isn't properly preserved during the request for the image and JSF won't be able to invoke the getter during the right iteration round. A view scoped bean would also not work as the JSF view state is nowhere available when the browser actually requests the image.





          To solve this problem, your best bet is to rewrite the getter method as such so that it can be invoked on a per-request basis wherein you pass the unique image identifier as a <f:param> instead of relying on some backing bean properties which may go "out of sync" during subsequent HTTP requests. It would make completely sense to use a separate application scoped managed bean for this which doesn't have any state. Moreover, an InputStream can be read only once, not multiple times.



          In other words: never declare StreamedContent nor any InputStream or even UploadedFile as a bean property; only create it brand-new in the getter of a stateless @ApplicationScoped bean when the webbrowser actually requests the image content.



          E.g.



          <p:dataTable value="#{bean.students}" var="student">
          <p:column>
          <p:graphicImage value="#{studentImages.image}">
          <f:param name="studentId" value="#{student.id}" />
          </p:graphicImage>
          </p:column>
          </p:dataTable>


          Where the StudentImages backing bean can look like this:



          @Named // Or @ManagedBean
          @ApplicationScoped
          public class StudentImages {

          @EJB
          private StudentService service;

          public StreamedContent getImage() throws IOException {
          FacesContext context = FacesContext.getCurrentInstance();

          if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
          // So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
          return new DefaultStreamedContent();
          }
          else {
          // So, browser is requesting the image. Return a real StreamedContent with the image bytes.
          String studentId = context.getExternalContext().getRequestParameterMap().get("studentId");
          Student student = studentService.find(Long.valueOf(studentId));
          return new DefaultStreamedContent(new ByteArrayInputStream(student.getImage()));
          }
          }

          }


          Please note that this is a very special case wherein performing business logic in a getter method is completely legit, considering how the <p:graphicImage> works under the covers. Invoking business logic in getters is namely usually frowned upon, see also Why JSF calls getters multiple times. Don't use this special case as excuse for other standard (non-special) cases. Please also note that you can't make use of EL 2.2 feature of passing method arguments like so #{studentImages.image(student.id)} because this argument won't end up in the image URL. Thus you really need to pass them as <f:param>.





          If you happen to use OmniFaces 2.0 or newer, then consider using its <o:graphicImage> instead which can be used more intuitively, with an application scoped getter method directly delegating to the service method and supporting EL 2.2 method arguments.



          Thus so:



          <p:dataTable value="#{bean.students}" var="student">
          <p:column>
          <o:graphicImage value="#{studentImages.getImage(student.id)}" />
          </p:column>
          </p:dataTable>


          With



          @Named // Or @ManagedBean
          @ApplicationScoped
          public class StudentImages {

          @EJB
          private StudentService service;

          public byte getImage(Long studentId) {
          return studentService.find(studentId).getImage();
          }

          }


          See also the blog on the subject.






          share|improve this answer





















          • 1





            BalusC, this is exactly what I was looking for, however I just couldn't figure out how the response should be sent back to the client. You're truly a legend. Thank you very much. :)

            – Lyubomyr Shaydariv
            Mar 20 '13 at 14:43











          • @Lyu: you're welcome.

            – BalusC
            Mar 20 '13 at 14:44











          • @BalusC Is it possible to use ManageBean with RequestScope. How to render dynamic image with RequestScope bean?

            – Zaw Than oo
            Jan 17 '14 at 4:59






          • 1





            @Tiny: EJBs and CDI managed beans are injected as proxies. The method call on the proxy instance basically locates the current instance in their scope and then invokes the desired method on it. You see this easily back in stacktraces from exceptions coming from those methods. Their scope is therefore not tied to the scope of the client and can easily be smaller.

            – BalusC
            May 28 '14 at 5:00








          • 1





            @Xtreme: consider moving on before it's too late.

            – BalusC
            Dec 19 '14 at 9:03



















          5














          Try including a mime type. In your posted example, you have it as "". The blank image may be because it doesn't recognize the stream as a image file since you made that field an empty string. So add a mime type of image/png or image/jpg and see if that works:



          String mimeType = "image/jpg";
          StreamedContent file = new DefaultStreamedContent(bytes, mimeType, filename);





          share|improve this answer































            4














            There's a couple possibilities here (and please post the entire class if this isn't it).



            1) You're not initializing the image properly
            2) Your stream is empty so you're getting nothing



            I'm assuming student.getImage() has a signature of byte so first make sure that that data is actually intact and represents an image. Secondly--you're not specifying a content-type which should be "image/jpg" or whatever you're using.



            Here's some boilerplate code to check it with, I'm using Primefaces 2 for this.



            /** 'test' package with 'test/test.png' on the path */
            @RequestScoped
            @ManagedBean(name="imageBean")
            public class ImageBean
            {
            private DefaultStreamedContent content;

            public StreamedContent getContent()
            {
            if(content == null)
            {
            /* use your database call here */
            BufferedInputStream in = new BufferedInputStream(ImageBean.class.getClassLoader().getResourceAsStream("test/test.png"));
            ByteArrayOutputStream out = new ByteArrayOutputStream();

            int val = -1;
            /* this is a simple test method to double check values from the stream */
            try
            {
            while((val = in.read()) != -1)
            out.write(val);
            }
            catch(IOException e)
            {
            e.printStackTrace();
            }

            byte bytes = out.toByteArray();
            System.out.println("Bytes -> " + bytes.length);
            content = new DefaultStreamedContent(new ByteArrayInputStream(bytes), "image/png", "test.png");
            }

            return content;
            }
            }


            and some markup...



            <html 
            xmlns="http://www.w3.org/1999/xhtml"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:p="http://primefaces.prime.com.tr/ui"
            >

            <h:head>

            </h:head>

            <h:body>
            <p:graphicImage value="#{imageBean.content}" />
            </h:body>
            </html>


            If that code works then you're set up properly. Despite the fact it is garbage code for the streams (don't use it in production) it should give you a point to troubleshoot from. My guess is that you might have something happening in your JPA or other Database framework where you're byte is empty or it is formatted wrong. Alternatively you could just have a content-type problem.



            Lastly, I would clone the data from the bean so that student.getImage() would only be copied into a new array and then used. This way if you have something unknown going on (something else moving the object or changing the byte you're not messing with your streams.



            Do something like:



            byte data = new byte[student.getImage().length]
            for(int i = 0; i < data.length; i++)
            data[i] = student.getImage()[i];


            so that your bean has a copy (or Arrays.copy()--whatever floats your boat). I can't stress enough how something simple like this/content type is usually what's wrong. Good luck with it.






            share|improve this answer































              3














              The answer from BalusC is (as usual) the correct one.



              But keep one thing (as already stated by him) in mind. The final request is done from the browser to get the URL from the constructed <img> tag. This is not done in a 'jsf context'.



              So if you try to e.g. access the phaseId (logging or whatever reason)



              context.getCurrentPhaseId().getName()


              This will result in a NullPointerException and the somehow misleading error message you will get is:



              org.primefaces.application.resource.StreamedContentHandler () - Error in streaming dynamic resource. Error reading 'image' on type a.b.SomeBean


              It took me quite some time to figure out what was the problem.






              share|improve this answer
























                protected by BalusC Jul 7 '16 at 11:07



                Thank you for your interest in this question.
                Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                Would you like to answer one of these unanswered questions instead?














                4 Answers
                4






                active

                oldest

                votes








                4 Answers
                4






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                89














                The <p:graphicImage> requires a special getter method. It will namely be invoked twice per generated image, each in a completely different HTTP request.



                The first HTTP request, which has requested the HTML result of a JSF page, will invoke the getter for the first time in order to generate the HTML <img> element with the right unique and auto-generated URL in the src attribute which contains information about which bean and getter exactly should be invoked whenever the webbrowser is about to request the image. Note that the getter does at this moment not need to return the image's contents. It would not be used in any way as that's not how HTML works (images are not "inlined" in HTML output, but they are instead requested separately).



                Once the webbrowser retrieves the HTML result as HTTP response, it will parse the HTML source in order to present the result visually to the enduser. Once the webbrowser encounters an <img> element during parsing the HTML source, then it will send a brand new HTTP request on the URL as specified in its src attribute in order to download the content of that image and embed it in the visual presentation. This will invoke the getter method for the second time which in turn should return the actual image content.



                In your particular case PrimeFaces was apparently either unable to identify and invoke the getter in order to retrieve the actual image content, or the getter didn't return the expected image content. The usage of #{item} variable name and the lot of calls in the log suggests that you were using it in an <ui:repeat> or a <h:dataTable>. Most likely the backing bean is request scoped and the datamodel isn't properly preserved during the request for the image and JSF won't be able to invoke the getter during the right iteration round. A view scoped bean would also not work as the JSF view state is nowhere available when the browser actually requests the image.





                To solve this problem, your best bet is to rewrite the getter method as such so that it can be invoked on a per-request basis wherein you pass the unique image identifier as a <f:param> instead of relying on some backing bean properties which may go "out of sync" during subsequent HTTP requests. It would make completely sense to use a separate application scoped managed bean for this which doesn't have any state. Moreover, an InputStream can be read only once, not multiple times.



                In other words: never declare StreamedContent nor any InputStream or even UploadedFile as a bean property; only create it brand-new in the getter of a stateless @ApplicationScoped bean when the webbrowser actually requests the image content.



                E.g.



                <p:dataTable value="#{bean.students}" var="student">
                <p:column>
                <p:graphicImage value="#{studentImages.image}">
                <f:param name="studentId" value="#{student.id}" />
                </p:graphicImage>
                </p:column>
                </p:dataTable>


                Where the StudentImages backing bean can look like this:



                @Named // Or @ManagedBean
                @ApplicationScoped
                public class StudentImages {

                @EJB
                private StudentService service;

                public StreamedContent getImage() throws IOException {
                FacesContext context = FacesContext.getCurrentInstance();

                if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
                // So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
                return new DefaultStreamedContent();
                }
                else {
                // So, browser is requesting the image. Return a real StreamedContent with the image bytes.
                String studentId = context.getExternalContext().getRequestParameterMap().get("studentId");
                Student student = studentService.find(Long.valueOf(studentId));
                return new DefaultStreamedContent(new ByteArrayInputStream(student.getImage()));
                }
                }

                }


                Please note that this is a very special case wherein performing business logic in a getter method is completely legit, considering how the <p:graphicImage> works under the covers. Invoking business logic in getters is namely usually frowned upon, see also Why JSF calls getters multiple times. Don't use this special case as excuse for other standard (non-special) cases. Please also note that you can't make use of EL 2.2 feature of passing method arguments like so #{studentImages.image(student.id)} because this argument won't end up in the image URL. Thus you really need to pass them as <f:param>.





                If you happen to use OmniFaces 2.0 or newer, then consider using its <o:graphicImage> instead which can be used more intuitively, with an application scoped getter method directly delegating to the service method and supporting EL 2.2 method arguments.



                Thus so:



                <p:dataTable value="#{bean.students}" var="student">
                <p:column>
                <o:graphicImage value="#{studentImages.getImage(student.id)}" />
                </p:column>
                </p:dataTable>


                With



                @Named // Or @ManagedBean
                @ApplicationScoped
                public class StudentImages {

                @EJB
                private StudentService service;

                public byte getImage(Long studentId) {
                return studentService.find(studentId).getImage();
                }

                }


                See also the blog on the subject.






                share|improve this answer





















                • 1





                  BalusC, this is exactly what I was looking for, however I just couldn't figure out how the response should be sent back to the client. You're truly a legend. Thank you very much. :)

                  – Lyubomyr Shaydariv
                  Mar 20 '13 at 14:43











                • @Lyu: you're welcome.

                  – BalusC
                  Mar 20 '13 at 14:44











                • @BalusC Is it possible to use ManageBean with RequestScope. How to render dynamic image with RequestScope bean?

                  – Zaw Than oo
                  Jan 17 '14 at 4:59






                • 1





                  @Tiny: EJBs and CDI managed beans are injected as proxies. The method call on the proxy instance basically locates the current instance in their scope and then invokes the desired method on it. You see this easily back in stacktraces from exceptions coming from those methods. Their scope is therefore not tied to the scope of the client and can easily be smaller.

                  – BalusC
                  May 28 '14 at 5:00








                • 1





                  @Xtreme: consider moving on before it's too late.

                  – BalusC
                  Dec 19 '14 at 9:03
















                89














                The <p:graphicImage> requires a special getter method. It will namely be invoked twice per generated image, each in a completely different HTTP request.



                The first HTTP request, which has requested the HTML result of a JSF page, will invoke the getter for the first time in order to generate the HTML <img> element with the right unique and auto-generated URL in the src attribute which contains information about which bean and getter exactly should be invoked whenever the webbrowser is about to request the image. Note that the getter does at this moment not need to return the image's contents. It would not be used in any way as that's not how HTML works (images are not "inlined" in HTML output, but they are instead requested separately).



                Once the webbrowser retrieves the HTML result as HTTP response, it will parse the HTML source in order to present the result visually to the enduser. Once the webbrowser encounters an <img> element during parsing the HTML source, then it will send a brand new HTTP request on the URL as specified in its src attribute in order to download the content of that image and embed it in the visual presentation. This will invoke the getter method for the second time which in turn should return the actual image content.



                In your particular case PrimeFaces was apparently either unable to identify and invoke the getter in order to retrieve the actual image content, or the getter didn't return the expected image content. The usage of #{item} variable name and the lot of calls in the log suggests that you were using it in an <ui:repeat> or a <h:dataTable>. Most likely the backing bean is request scoped and the datamodel isn't properly preserved during the request for the image and JSF won't be able to invoke the getter during the right iteration round. A view scoped bean would also not work as the JSF view state is nowhere available when the browser actually requests the image.





                To solve this problem, your best bet is to rewrite the getter method as such so that it can be invoked on a per-request basis wherein you pass the unique image identifier as a <f:param> instead of relying on some backing bean properties which may go "out of sync" during subsequent HTTP requests. It would make completely sense to use a separate application scoped managed bean for this which doesn't have any state. Moreover, an InputStream can be read only once, not multiple times.



                In other words: never declare StreamedContent nor any InputStream or even UploadedFile as a bean property; only create it brand-new in the getter of a stateless @ApplicationScoped bean when the webbrowser actually requests the image content.



                E.g.



                <p:dataTable value="#{bean.students}" var="student">
                <p:column>
                <p:graphicImage value="#{studentImages.image}">
                <f:param name="studentId" value="#{student.id}" />
                </p:graphicImage>
                </p:column>
                </p:dataTable>


                Where the StudentImages backing bean can look like this:



                @Named // Or @ManagedBean
                @ApplicationScoped
                public class StudentImages {

                @EJB
                private StudentService service;

                public StreamedContent getImage() throws IOException {
                FacesContext context = FacesContext.getCurrentInstance();

                if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
                // So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
                return new DefaultStreamedContent();
                }
                else {
                // So, browser is requesting the image. Return a real StreamedContent with the image bytes.
                String studentId = context.getExternalContext().getRequestParameterMap().get("studentId");
                Student student = studentService.find(Long.valueOf(studentId));
                return new DefaultStreamedContent(new ByteArrayInputStream(student.getImage()));
                }
                }

                }


                Please note that this is a very special case wherein performing business logic in a getter method is completely legit, considering how the <p:graphicImage> works under the covers. Invoking business logic in getters is namely usually frowned upon, see also Why JSF calls getters multiple times. Don't use this special case as excuse for other standard (non-special) cases. Please also note that you can't make use of EL 2.2 feature of passing method arguments like so #{studentImages.image(student.id)} because this argument won't end up in the image URL. Thus you really need to pass them as <f:param>.





                If you happen to use OmniFaces 2.0 or newer, then consider using its <o:graphicImage> instead which can be used more intuitively, with an application scoped getter method directly delegating to the service method and supporting EL 2.2 method arguments.



                Thus so:



                <p:dataTable value="#{bean.students}" var="student">
                <p:column>
                <o:graphicImage value="#{studentImages.getImage(student.id)}" />
                </p:column>
                </p:dataTable>


                With



                @Named // Or @ManagedBean
                @ApplicationScoped
                public class StudentImages {

                @EJB
                private StudentService service;

                public byte getImage(Long studentId) {
                return studentService.find(studentId).getImage();
                }

                }


                See also the blog on the subject.






                share|improve this answer





















                • 1





                  BalusC, this is exactly what I was looking for, however I just couldn't figure out how the response should be sent back to the client. You're truly a legend. Thank you very much. :)

                  – Lyubomyr Shaydariv
                  Mar 20 '13 at 14:43











                • @Lyu: you're welcome.

                  – BalusC
                  Mar 20 '13 at 14:44











                • @BalusC Is it possible to use ManageBean with RequestScope. How to render dynamic image with RequestScope bean?

                  – Zaw Than oo
                  Jan 17 '14 at 4:59






                • 1





                  @Tiny: EJBs and CDI managed beans are injected as proxies. The method call on the proxy instance basically locates the current instance in their scope and then invokes the desired method on it. You see this easily back in stacktraces from exceptions coming from those methods. Their scope is therefore not tied to the scope of the client and can easily be smaller.

                  – BalusC
                  May 28 '14 at 5:00








                • 1





                  @Xtreme: consider moving on before it's too late.

                  – BalusC
                  Dec 19 '14 at 9:03














                89












                89








                89







                The <p:graphicImage> requires a special getter method. It will namely be invoked twice per generated image, each in a completely different HTTP request.



                The first HTTP request, which has requested the HTML result of a JSF page, will invoke the getter for the first time in order to generate the HTML <img> element with the right unique and auto-generated URL in the src attribute which contains information about which bean and getter exactly should be invoked whenever the webbrowser is about to request the image. Note that the getter does at this moment not need to return the image's contents. It would not be used in any way as that's not how HTML works (images are not "inlined" in HTML output, but they are instead requested separately).



                Once the webbrowser retrieves the HTML result as HTTP response, it will parse the HTML source in order to present the result visually to the enduser. Once the webbrowser encounters an <img> element during parsing the HTML source, then it will send a brand new HTTP request on the URL as specified in its src attribute in order to download the content of that image and embed it in the visual presentation. This will invoke the getter method for the second time which in turn should return the actual image content.



                In your particular case PrimeFaces was apparently either unable to identify and invoke the getter in order to retrieve the actual image content, or the getter didn't return the expected image content. The usage of #{item} variable name and the lot of calls in the log suggests that you were using it in an <ui:repeat> or a <h:dataTable>. Most likely the backing bean is request scoped and the datamodel isn't properly preserved during the request for the image and JSF won't be able to invoke the getter during the right iteration round. A view scoped bean would also not work as the JSF view state is nowhere available when the browser actually requests the image.





                To solve this problem, your best bet is to rewrite the getter method as such so that it can be invoked on a per-request basis wherein you pass the unique image identifier as a <f:param> instead of relying on some backing bean properties which may go "out of sync" during subsequent HTTP requests. It would make completely sense to use a separate application scoped managed bean for this which doesn't have any state. Moreover, an InputStream can be read only once, not multiple times.



                In other words: never declare StreamedContent nor any InputStream or even UploadedFile as a bean property; only create it brand-new in the getter of a stateless @ApplicationScoped bean when the webbrowser actually requests the image content.



                E.g.



                <p:dataTable value="#{bean.students}" var="student">
                <p:column>
                <p:graphicImage value="#{studentImages.image}">
                <f:param name="studentId" value="#{student.id}" />
                </p:graphicImage>
                </p:column>
                </p:dataTable>


                Where the StudentImages backing bean can look like this:



                @Named // Or @ManagedBean
                @ApplicationScoped
                public class StudentImages {

                @EJB
                private StudentService service;

                public StreamedContent getImage() throws IOException {
                FacesContext context = FacesContext.getCurrentInstance();

                if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
                // So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
                return new DefaultStreamedContent();
                }
                else {
                // So, browser is requesting the image. Return a real StreamedContent with the image bytes.
                String studentId = context.getExternalContext().getRequestParameterMap().get("studentId");
                Student student = studentService.find(Long.valueOf(studentId));
                return new DefaultStreamedContent(new ByteArrayInputStream(student.getImage()));
                }
                }

                }


                Please note that this is a very special case wherein performing business logic in a getter method is completely legit, considering how the <p:graphicImage> works under the covers. Invoking business logic in getters is namely usually frowned upon, see also Why JSF calls getters multiple times. Don't use this special case as excuse for other standard (non-special) cases. Please also note that you can't make use of EL 2.2 feature of passing method arguments like so #{studentImages.image(student.id)} because this argument won't end up in the image URL. Thus you really need to pass them as <f:param>.





                If you happen to use OmniFaces 2.0 or newer, then consider using its <o:graphicImage> instead which can be used more intuitively, with an application scoped getter method directly delegating to the service method and supporting EL 2.2 method arguments.



                Thus so:



                <p:dataTable value="#{bean.students}" var="student">
                <p:column>
                <o:graphicImage value="#{studentImages.getImage(student.id)}" />
                </p:column>
                </p:dataTable>


                With



                @Named // Or @ManagedBean
                @ApplicationScoped
                public class StudentImages {

                @EJB
                private StudentService service;

                public byte getImage(Long studentId) {
                return studentService.find(studentId).getImage();
                }

                }


                See also the blog on the subject.






                share|improve this answer















                The <p:graphicImage> requires a special getter method. It will namely be invoked twice per generated image, each in a completely different HTTP request.



                The first HTTP request, which has requested the HTML result of a JSF page, will invoke the getter for the first time in order to generate the HTML <img> element with the right unique and auto-generated URL in the src attribute which contains information about which bean and getter exactly should be invoked whenever the webbrowser is about to request the image. Note that the getter does at this moment not need to return the image's contents. It would not be used in any way as that's not how HTML works (images are not "inlined" in HTML output, but they are instead requested separately).



                Once the webbrowser retrieves the HTML result as HTTP response, it will parse the HTML source in order to present the result visually to the enduser. Once the webbrowser encounters an <img> element during parsing the HTML source, then it will send a brand new HTTP request on the URL as specified in its src attribute in order to download the content of that image and embed it in the visual presentation. This will invoke the getter method for the second time which in turn should return the actual image content.



                In your particular case PrimeFaces was apparently either unable to identify and invoke the getter in order to retrieve the actual image content, or the getter didn't return the expected image content. The usage of #{item} variable name and the lot of calls in the log suggests that you were using it in an <ui:repeat> or a <h:dataTable>. Most likely the backing bean is request scoped and the datamodel isn't properly preserved during the request for the image and JSF won't be able to invoke the getter during the right iteration round. A view scoped bean would also not work as the JSF view state is nowhere available when the browser actually requests the image.





                To solve this problem, your best bet is to rewrite the getter method as such so that it can be invoked on a per-request basis wherein you pass the unique image identifier as a <f:param> instead of relying on some backing bean properties which may go "out of sync" during subsequent HTTP requests. It would make completely sense to use a separate application scoped managed bean for this which doesn't have any state. Moreover, an InputStream can be read only once, not multiple times.



                In other words: never declare StreamedContent nor any InputStream or even UploadedFile as a bean property; only create it brand-new in the getter of a stateless @ApplicationScoped bean when the webbrowser actually requests the image content.



                E.g.



                <p:dataTable value="#{bean.students}" var="student">
                <p:column>
                <p:graphicImage value="#{studentImages.image}">
                <f:param name="studentId" value="#{student.id}" />
                </p:graphicImage>
                </p:column>
                </p:dataTable>


                Where the StudentImages backing bean can look like this:



                @Named // Or @ManagedBean
                @ApplicationScoped
                public class StudentImages {

                @EJB
                private StudentService service;

                public StreamedContent getImage() throws IOException {
                FacesContext context = FacesContext.getCurrentInstance();

                if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
                // So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
                return new DefaultStreamedContent();
                }
                else {
                // So, browser is requesting the image. Return a real StreamedContent with the image bytes.
                String studentId = context.getExternalContext().getRequestParameterMap().get("studentId");
                Student student = studentService.find(Long.valueOf(studentId));
                return new DefaultStreamedContent(new ByteArrayInputStream(student.getImage()));
                }
                }

                }


                Please note that this is a very special case wherein performing business logic in a getter method is completely legit, considering how the <p:graphicImage> works under the covers. Invoking business logic in getters is namely usually frowned upon, see also Why JSF calls getters multiple times. Don't use this special case as excuse for other standard (non-special) cases. Please also note that you can't make use of EL 2.2 feature of passing method arguments like so #{studentImages.image(student.id)} because this argument won't end up in the image URL. Thus you really need to pass them as <f:param>.





                If you happen to use OmniFaces 2.0 or newer, then consider using its <o:graphicImage> instead which can be used more intuitively, with an application scoped getter method directly delegating to the service method and supporting EL 2.2 method arguments.



                Thus so:



                <p:dataTable value="#{bean.students}" var="student">
                <p:column>
                <o:graphicImage value="#{studentImages.getImage(student.id)}" />
                </p:column>
                </p:dataTable>


                With



                @Named // Or @ManagedBean
                @ApplicationScoped
                public class StudentImages {

                @EJB
                private StudentService service;

                public byte getImage(Long studentId) {
                return studentService.find(studentId).getImage();
                }

                }


                See also the blog on the subject.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited May 23 '17 at 12:10









                Community

                11




                11










                answered Sep 17 '12 at 1:26









                BalusCBalusC

                847k29831423217




                847k29831423217








                • 1





                  BalusC, this is exactly what I was looking for, however I just couldn't figure out how the response should be sent back to the client. You're truly a legend. Thank you very much. :)

                  – Lyubomyr Shaydariv
                  Mar 20 '13 at 14:43











                • @Lyu: you're welcome.

                  – BalusC
                  Mar 20 '13 at 14:44











                • @BalusC Is it possible to use ManageBean with RequestScope. How to render dynamic image with RequestScope bean?

                  – Zaw Than oo
                  Jan 17 '14 at 4:59






                • 1





                  @Tiny: EJBs and CDI managed beans are injected as proxies. The method call on the proxy instance basically locates the current instance in their scope and then invokes the desired method on it. You see this easily back in stacktraces from exceptions coming from those methods. Their scope is therefore not tied to the scope of the client and can easily be smaller.

                  – BalusC
                  May 28 '14 at 5:00








                • 1





                  @Xtreme: consider moving on before it's too late.

                  – BalusC
                  Dec 19 '14 at 9:03














                • 1





                  BalusC, this is exactly what I was looking for, however I just couldn't figure out how the response should be sent back to the client. You're truly a legend. Thank you very much. :)

                  – Lyubomyr Shaydariv
                  Mar 20 '13 at 14:43











                • @Lyu: you're welcome.

                  – BalusC
                  Mar 20 '13 at 14:44











                • @BalusC Is it possible to use ManageBean with RequestScope. How to render dynamic image with RequestScope bean?

                  – Zaw Than oo
                  Jan 17 '14 at 4:59






                • 1





                  @Tiny: EJBs and CDI managed beans are injected as proxies. The method call on the proxy instance basically locates the current instance in their scope and then invokes the desired method on it. You see this easily back in stacktraces from exceptions coming from those methods. Their scope is therefore not tied to the scope of the client and can easily be smaller.

                  – BalusC
                  May 28 '14 at 5:00








                • 1





                  @Xtreme: consider moving on before it's too late.

                  – BalusC
                  Dec 19 '14 at 9:03








                1




                1





                BalusC, this is exactly what I was looking for, however I just couldn't figure out how the response should be sent back to the client. You're truly a legend. Thank you very much. :)

                – Lyubomyr Shaydariv
                Mar 20 '13 at 14:43





                BalusC, this is exactly what I was looking for, however I just couldn't figure out how the response should be sent back to the client. You're truly a legend. Thank you very much. :)

                – Lyubomyr Shaydariv
                Mar 20 '13 at 14:43













                @Lyu: you're welcome.

                – BalusC
                Mar 20 '13 at 14:44





                @Lyu: you're welcome.

                – BalusC
                Mar 20 '13 at 14:44













                @BalusC Is it possible to use ManageBean with RequestScope. How to render dynamic image with RequestScope bean?

                – Zaw Than oo
                Jan 17 '14 at 4:59





                @BalusC Is it possible to use ManageBean with RequestScope. How to render dynamic image with RequestScope bean?

                – Zaw Than oo
                Jan 17 '14 at 4:59




                1




                1





                @Tiny: EJBs and CDI managed beans are injected as proxies. The method call on the proxy instance basically locates the current instance in their scope and then invokes the desired method on it. You see this easily back in stacktraces from exceptions coming from those methods. Their scope is therefore not tied to the scope of the client and can easily be smaller.

                – BalusC
                May 28 '14 at 5:00







                @Tiny: EJBs and CDI managed beans are injected as proxies. The method call on the proxy instance basically locates the current instance in their scope and then invokes the desired method on it. You see this easily back in stacktraces from exceptions coming from those methods. Their scope is therefore not tied to the scope of the client and can easily be smaller.

                – BalusC
                May 28 '14 at 5:00






                1




                1





                @Xtreme: consider moving on before it's too late.

                – BalusC
                Dec 19 '14 at 9:03





                @Xtreme: consider moving on before it's too late.

                – BalusC
                Dec 19 '14 at 9:03













                5














                Try including a mime type. In your posted example, you have it as "". The blank image may be because it doesn't recognize the stream as a image file since you made that field an empty string. So add a mime type of image/png or image/jpg and see if that works:



                String mimeType = "image/jpg";
                StreamedContent file = new DefaultStreamedContent(bytes, mimeType, filename);





                share|improve this answer




























                  5














                  Try including a mime type. In your posted example, you have it as "". The blank image may be because it doesn't recognize the stream as a image file since you made that field an empty string. So add a mime type of image/png or image/jpg and see if that works:



                  String mimeType = "image/jpg";
                  StreamedContent file = new DefaultStreamedContent(bytes, mimeType, filename);





                  share|improve this answer


























                    5












                    5








                    5







                    Try including a mime type. In your posted example, you have it as "". The blank image may be because it doesn't recognize the stream as a image file since you made that field an empty string. So add a mime type of image/png or image/jpg and see if that works:



                    String mimeType = "image/jpg";
                    StreamedContent file = new DefaultStreamedContent(bytes, mimeType, filename);





                    share|improve this answer













                    Try including a mime type. In your posted example, you have it as "". The blank image may be because it doesn't recognize the stream as a image file since you made that field an empty string. So add a mime type of image/png or image/jpg and see if that works:



                    String mimeType = "image/jpg";
                    StreamedContent file = new DefaultStreamedContent(bytes, mimeType, filename);






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Sep 26 '12 at 22:24









                    rcheukrcheuk

                    8251123




                    8251123























                        4














                        There's a couple possibilities here (and please post the entire class if this isn't it).



                        1) You're not initializing the image properly
                        2) Your stream is empty so you're getting nothing



                        I'm assuming student.getImage() has a signature of byte so first make sure that that data is actually intact and represents an image. Secondly--you're not specifying a content-type which should be "image/jpg" or whatever you're using.



                        Here's some boilerplate code to check it with, I'm using Primefaces 2 for this.



                        /** 'test' package with 'test/test.png' on the path */
                        @RequestScoped
                        @ManagedBean(name="imageBean")
                        public class ImageBean
                        {
                        private DefaultStreamedContent content;

                        public StreamedContent getContent()
                        {
                        if(content == null)
                        {
                        /* use your database call here */
                        BufferedInputStream in = new BufferedInputStream(ImageBean.class.getClassLoader().getResourceAsStream("test/test.png"));
                        ByteArrayOutputStream out = new ByteArrayOutputStream();

                        int val = -1;
                        /* this is a simple test method to double check values from the stream */
                        try
                        {
                        while((val = in.read()) != -1)
                        out.write(val);
                        }
                        catch(IOException e)
                        {
                        e.printStackTrace();
                        }

                        byte bytes = out.toByteArray();
                        System.out.println("Bytes -> " + bytes.length);
                        content = new DefaultStreamedContent(new ByteArrayInputStream(bytes), "image/png", "test.png");
                        }

                        return content;
                        }
                        }


                        and some markup...



                        <html 
                        xmlns="http://www.w3.org/1999/xhtml"
                        xmlns:h="http://java.sun.com/jsf/html"
                        xmlns:p="http://primefaces.prime.com.tr/ui"
                        >

                        <h:head>

                        </h:head>

                        <h:body>
                        <p:graphicImage value="#{imageBean.content}" />
                        </h:body>
                        </html>


                        If that code works then you're set up properly. Despite the fact it is garbage code for the streams (don't use it in production) it should give you a point to troubleshoot from. My guess is that you might have something happening in your JPA or other Database framework where you're byte is empty or it is formatted wrong. Alternatively you could just have a content-type problem.



                        Lastly, I would clone the data from the bean so that student.getImage() would only be copied into a new array and then used. This way if you have something unknown going on (something else moving the object or changing the byte you're not messing with your streams.



                        Do something like:



                        byte data = new byte[student.getImage().length]
                        for(int i = 0; i < data.length; i++)
                        data[i] = student.getImage()[i];


                        so that your bean has a copy (or Arrays.copy()--whatever floats your boat). I can't stress enough how something simple like this/content type is usually what's wrong. Good luck with it.






                        share|improve this answer




























                          4














                          There's a couple possibilities here (and please post the entire class if this isn't it).



                          1) You're not initializing the image properly
                          2) Your stream is empty so you're getting nothing



                          I'm assuming student.getImage() has a signature of byte so first make sure that that data is actually intact and represents an image. Secondly--you're not specifying a content-type which should be "image/jpg" or whatever you're using.



                          Here's some boilerplate code to check it with, I'm using Primefaces 2 for this.



                          /** 'test' package with 'test/test.png' on the path */
                          @RequestScoped
                          @ManagedBean(name="imageBean")
                          public class ImageBean
                          {
                          private DefaultStreamedContent content;

                          public StreamedContent getContent()
                          {
                          if(content == null)
                          {
                          /* use your database call here */
                          BufferedInputStream in = new BufferedInputStream(ImageBean.class.getClassLoader().getResourceAsStream("test/test.png"));
                          ByteArrayOutputStream out = new ByteArrayOutputStream();

                          int val = -1;
                          /* this is a simple test method to double check values from the stream */
                          try
                          {
                          while((val = in.read()) != -1)
                          out.write(val);
                          }
                          catch(IOException e)
                          {
                          e.printStackTrace();
                          }

                          byte bytes = out.toByteArray();
                          System.out.println("Bytes -> " + bytes.length);
                          content = new DefaultStreamedContent(new ByteArrayInputStream(bytes), "image/png", "test.png");
                          }

                          return content;
                          }
                          }


                          and some markup...



                          <html 
                          xmlns="http://www.w3.org/1999/xhtml"
                          xmlns:h="http://java.sun.com/jsf/html"
                          xmlns:p="http://primefaces.prime.com.tr/ui"
                          >

                          <h:head>

                          </h:head>

                          <h:body>
                          <p:graphicImage value="#{imageBean.content}" />
                          </h:body>
                          </html>


                          If that code works then you're set up properly. Despite the fact it is garbage code for the streams (don't use it in production) it should give you a point to troubleshoot from. My guess is that you might have something happening in your JPA or other Database framework where you're byte is empty or it is formatted wrong. Alternatively you could just have a content-type problem.



                          Lastly, I would clone the data from the bean so that student.getImage() would only be copied into a new array and then used. This way if you have something unknown going on (something else moving the object or changing the byte you're not messing with your streams.



                          Do something like:



                          byte data = new byte[student.getImage().length]
                          for(int i = 0; i < data.length; i++)
                          data[i] = student.getImage()[i];


                          so that your bean has a copy (or Arrays.copy()--whatever floats your boat). I can't stress enough how something simple like this/content type is usually what's wrong. Good luck with it.






                          share|improve this answer


























                            4












                            4








                            4







                            There's a couple possibilities here (and please post the entire class if this isn't it).



                            1) You're not initializing the image properly
                            2) Your stream is empty so you're getting nothing



                            I'm assuming student.getImage() has a signature of byte so first make sure that that data is actually intact and represents an image. Secondly--you're not specifying a content-type which should be "image/jpg" or whatever you're using.



                            Here's some boilerplate code to check it with, I'm using Primefaces 2 for this.



                            /** 'test' package with 'test/test.png' on the path */
                            @RequestScoped
                            @ManagedBean(name="imageBean")
                            public class ImageBean
                            {
                            private DefaultStreamedContent content;

                            public StreamedContent getContent()
                            {
                            if(content == null)
                            {
                            /* use your database call here */
                            BufferedInputStream in = new BufferedInputStream(ImageBean.class.getClassLoader().getResourceAsStream("test/test.png"));
                            ByteArrayOutputStream out = new ByteArrayOutputStream();

                            int val = -1;
                            /* this is a simple test method to double check values from the stream */
                            try
                            {
                            while((val = in.read()) != -1)
                            out.write(val);
                            }
                            catch(IOException e)
                            {
                            e.printStackTrace();
                            }

                            byte bytes = out.toByteArray();
                            System.out.println("Bytes -> " + bytes.length);
                            content = new DefaultStreamedContent(new ByteArrayInputStream(bytes), "image/png", "test.png");
                            }

                            return content;
                            }
                            }


                            and some markup...



                            <html 
                            xmlns="http://www.w3.org/1999/xhtml"
                            xmlns:h="http://java.sun.com/jsf/html"
                            xmlns:p="http://primefaces.prime.com.tr/ui"
                            >

                            <h:head>

                            </h:head>

                            <h:body>
                            <p:graphicImage value="#{imageBean.content}" />
                            </h:body>
                            </html>


                            If that code works then you're set up properly. Despite the fact it is garbage code for the streams (don't use it in production) it should give you a point to troubleshoot from. My guess is that you might have something happening in your JPA or other Database framework where you're byte is empty or it is formatted wrong. Alternatively you could just have a content-type problem.



                            Lastly, I would clone the data from the bean so that student.getImage() would only be copied into a new array and then used. This way if you have something unknown going on (something else moving the object or changing the byte you're not messing with your streams.



                            Do something like:



                            byte data = new byte[student.getImage().length]
                            for(int i = 0; i < data.length; i++)
                            data[i] = student.getImage()[i];


                            so that your bean has a copy (or Arrays.copy()--whatever floats your boat). I can't stress enough how something simple like this/content type is usually what's wrong. Good luck with it.






                            share|improve this answer













                            There's a couple possibilities here (and please post the entire class if this isn't it).



                            1) You're not initializing the image properly
                            2) Your stream is empty so you're getting nothing



                            I'm assuming student.getImage() has a signature of byte so first make sure that that data is actually intact and represents an image. Secondly--you're not specifying a content-type which should be "image/jpg" or whatever you're using.



                            Here's some boilerplate code to check it with, I'm using Primefaces 2 for this.



                            /** 'test' package with 'test/test.png' on the path */
                            @RequestScoped
                            @ManagedBean(name="imageBean")
                            public class ImageBean
                            {
                            private DefaultStreamedContent content;

                            public StreamedContent getContent()
                            {
                            if(content == null)
                            {
                            /* use your database call here */
                            BufferedInputStream in = new BufferedInputStream(ImageBean.class.getClassLoader().getResourceAsStream("test/test.png"));
                            ByteArrayOutputStream out = new ByteArrayOutputStream();

                            int val = -1;
                            /* this is a simple test method to double check values from the stream */
                            try
                            {
                            while((val = in.read()) != -1)
                            out.write(val);
                            }
                            catch(IOException e)
                            {
                            e.printStackTrace();
                            }

                            byte bytes = out.toByteArray();
                            System.out.println("Bytes -> " + bytes.length);
                            content = new DefaultStreamedContent(new ByteArrayInputStream(bytes), "image/png", "test.png");
                            }

                            return content;
                            }
                            }


                            and some markup...



                            <html 
                            xmlns="http://www.w3.org/1999/xhtml"
                            xmlns:h="http://java.sun.com/jsf/html"
                            xmlns:p="http://primefaces.prime.com.tr/ui"
                            >

                            <h:head>

                            </h:head>

                            <h:body>
                            <p:graphicImage value="#{imageBean.content}" />
                            </h:body>
                            </html>


                            If that code works then you're set up properly. Despite the fact it is garbage code for the streams (don't use it in production) it should give you a point to troubleshoot from. My guess is that you might have something happening in your JPA or other Database framework where you're byte is empty or it is formatted wrong. Alternatively you could just have a content-type problem.



                            Lastly, I would clone the data from the bean so that student.getImage() would only be copied into a new array and then used. This way if you have something unknown going on (something else moving the object or changing the byte you're not messing with your streams.



                            Do something like:



                            byte data = new byte[student.getImage().length]
                            for(int i = 0; i < data.length; i++)
                            data[i] = student.getImage()[i];


                            so that your bean has a copy (or Arrays.copy()--whatever floats your boat). I can't stress enough how something simple like this/content type is usually what's wrong. Good luck with it.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 27 '11 at 17:48









                            Daniel B. ChapmanDaniel B. Chapman

                            3,5572335




                            3,5572335























                                3














                                The answer from BalusC is (as usual) the correct one.



                                But keep one thing (as already stated by him) in mind. The final request is done from the browser to get the URL from the constructed <img> tag. This is not done in a 'jsf context'.



                                So if you try to e.g. access the phaseId (logging or whatever reason)



                                context.getCurrentPhaseId().getName()


                                This will result in a NullPointerException and the somehow misleading error message you will get is:



                                org.primefaces.application.resource.StreamedContentHandler () - Error in streaming dynamic resource. Error reading 'image' on type a.b.SomeBean


                                It took me quite some time to figure out what was the problem.






                                share|improve this answer






























                                  3














                                  The answer from BalusC is (as usual) the correct one.



                                  But keep one thing (as already stated by him) in mind. The final request is done from the browser to get the URL from the constructed <img> tag. This is not done in a 'jsf context'.



                                  So if you try to e.g. access the phaseId (logging or whatever reason)



                                  context.getCurrentPhaseId().getName()


                                  This will result in a NullPointerException and the somehow misleading error message you will get is:



                                  org.primefaces.application.resource.StreamedContentHandler () - Error in streaming dynamic resource. Error reading 'image' on type a.b.SomeBean


                                  It took me quite some time to figure out what was the problem.






                                  share|improve this answer




























                                    3












                                    3








                                    3







                                    The answer from BalusC is (as usual) the correct one.



                                    But keep one thing (as already stated by him) in mind. The final request is done from the browser to get the URL from the constructed <img> tag. This is not done in a 'jsf context'.



                                    So if you try to e.g. access the phaseId (logging or whatever reason)



                                    context.getCurrentPhaseId().getName()


                                    This will result in a NullPointerException and the somehow misleading error message you will get is:



                                    org.primefaces.application.resource.StreamedContentHandler () - Error in streaming dynamic resource. Error reading 'image' on type a.b.SomeBean


                                    It took me quite some time to figure out what was the problem.






                                    share|improve this answer















                                    The answer from BalusC is (as usual) the correct one.



                                    But keep one thing (as already stated by him) in mind. The final request is done from the browser to get the URL from the constructed <img> tag. This is not done in a 'jsf context'.



                                    So if you try to e.g. access the phaseId (logging or whatever reason)



                                    context.getCurrentPhaseId().getName()


                                    This will result in a NullPointerException and the somehow misleading error message you will get is:



                                    org.primefaces.application.resource.StreamedContentHandler () - Error in streaming dynamic resource. Error reading 'image' on type a.b.SomeBean


                                    It took me quite some time to figure out what was the problem.







                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited May 23 '17 at 12:34









                                    Community

                                    11




                                    11










                                    answered Sep 1 '16 at 16:08









                                    morecoremorecore

                                    1851318




                                    1851318

















                                        protected by BalusC Jul 7 '16 at 11:07



                                        Thank you for your interest in this question.
                                        Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                        Would you like to answer one of these unanswered questions instead?



                                        Popular posts from this blog

                                        Ottavio Pratesi

                                        Tricia Helfer

                                        15 giugno