2

Displaying a BLOB image using <p:graphicImage> as follows.

<p:graphicImage value="#{categoryBean.image}">
    <f:param name="id" value="7"/>
</p:graphicImage>

Where CategoryBean has been defined as follows.

@Named
@ApplicationScoped
public class CategoryBean {

    @Inject
    private CategoryService service;

    public CategoryBean() {}

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

        if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            return new DefaultStreamedContent();
        } else {
            String id = context.getExternalContext().getRequestParameterMap().get("id");
            byte[] bytes = Utils.isNumber(id) ? service.findImageById(Long.parseLong(id)) : null;
            return bytes == null ? null : new DefaultStreamedContent(new ByteArrayInputStream(bytes));
        }
    }
}

Regarding the above approach, the following custom tag should work flawlessly but it fails to display the image on <p:graphicImage> with no error / exception.

<my:image bean="#{categoryBean}" property="image" paramName="id" paramValue="7"/>

The tag file is located under /WEB-INF/tags/image.xhtml.

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:p="http://primefaces.org/ui"
                xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
                xmlns:f="http://xmlns.jcp.org/jsf/core">

    <p:graphicImage value="#{bean[property]}">
        <f:param name="#{paramName}" value="#{paramValue}"/>
    </p:graphicImage>
</ui:composition>

The generated <img> tag seems to look fine :

<img id="form:j_idt4"
     src="/ContextPath/javax.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&amp;v=5.3&amp;pfdrid=IA0%2F7ZuBnGS%2BSzeb%2BHyPOTo4Pxp4hjI6&amp;pfdrt=sc&amp;id=7&amp;pfdrid_c=true"
     alt=""/>

It only returns a HTTP 404 error.

Is there any flaw in the definition of the custom tag given?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Tiny
  • 27,221
  • 105
  • 339
  • 599
  • 1
    I did not feel bad but are there some disguised PrimeFaces guys who dislike publicly exposing bugs in their software continuously down-voting, when I post a question uncovering a long-standing bug? – Tiny Feb 11 '16 at 15:24

1 Answers1

2

It's caused by the way how PrimeFaces <p:graphicImage> identifies image requests. Basically, it converts the exact value expression #{bean[property]} to string, encrypts it and then passes it as pfdrid value. When the webbrowser needs to download the image by a brand new HTTP request, that value expression is decrypted and evaluated in the "current" EL context. However, during that moment, there's nowhere a #{bean} nor #{property} available anywhere in the EL context because there's no means of a JSF view with tagfiles and all. Only request, session and application scoped beans are available in EL context.

There's nothing to do against this other than reporting an issue at PrimeFaces guys.

As to alternate solutions, OmniFaces <o:graphicImage> does a better job in this by inspecting the target bean/method during render response already instead of during streaming the image. It immediately inspects #{bean[property]}, discovers that it actually represents #{categoryBean.image}, and then succeeds. Just to be sure I tested it in a tagfile like you have and it works fine for me whereas the PF one indeed fails as described.

<o:graphicImage value="#{bean[property](paramValue)}" />

public byte[] getImage(Long id) throws IOException {
    return service.findImageById(id);
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • There a `java.lang.NullPointerException` straight using `` (OmniFaces 2.2 / Mojarra 2.2.12) - `java.lang.NullPointerException at org.omnifaces.el.MethodReference.(MethodReference.java:45)`. – Tiny Feb 11 '16 at 15:06
  • Property must of course be `getImage`. NPE is at least not right, code had to throw a `MethodNotFoundException` here. – BalusC Feb 11 '16 at 15:14
  • The cause is reported as `java.lang.NullPointerException`. – Tiny Feb 11 '16 at 15:33
  • I meant to say, OmniFaces shouldn't have thrown a NPE here. I fixed it a sec ago: https://github.com/omnifaces/omnifaces/commit/d78c9bb53bc9c6d5666b6c040a8e372648bb7a6f – BalusC Feb 11 '16 at 15:41
  • 1
    So tiny found a bug in both PrimeFaces and OmniFaces in one issue ;-) – Kukeltje Feb 11 '16 at 20:15