我在JBoss 7.1.1上使用PrimeFaces 3.2。

我正在尝试显示图像,该图像存储在<ui:repeat>的MySQL数据库的BLOB中。图像存储在byte[]中,然后按以下方式转换为StreamedContent:

InputStream stream = new ByteArrayInputStream(ingredient.getImage());
ingredient.setJsfImage(new DefaultStreamedContent(stream, "image/jpg"));

然后,我尝试将其显示在Facelet中,如下所示:
<ui:repeat var="ingredient" value="#{formBean.ingredientResultSet}">
    <p:panel id="resultsPanel" header="#{ingredient.location.shopName}">
        <p:graphicImage value="#{ingredient.jsfImage}" alt="No picture set" />
...

但是,加载页面时,JBoss中出现以下错误:



这是怎么引起的,我该如何解决?

最佳答案

您需要认识到<p:graphicImage>实际上仅使用URL呈现<img src>元素,然后在稍后将要解析所获取的HTML标记并呈现结果时由webbrowser单独调用。
因此,无论您在<p:graphicImage>的getter方法中执行什么操作,都必须按照可以在每个请求的基础上调用它的方式进行设计。因此,最明智的方法是使用<p:graphicImage>创建<f:param>,其中<p:graphicImage value>指向完全独立的请求或应用程序作用域的bean(因此绝对不是 View 或 session 作用域的),而<f:param value>指向唯一的图像标识符。
例如。

<p:graphicImage value="#{images.image}">
    <f:param name="id" value="#{someBean.imageId}" />
</p:graphicImage>
Images支持bean可能如下所示:
@Named
@ApplicationScoped
public class Images {

    @EJB
    private ImageService service;

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

        if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            // So, we're rendering the view. 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 id = context.getExternalContext().getRequestParameterMap().get("id");
            Image image = service.find(Long.valueOf(id));
            return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
        }
    }

}
或者,如果您已经在使用OmniFaces 2.0 or newer,那么可以考虑使用其 <o:graphicImage> ,它可以更直观,几乎按您期望的方式使用。另请参见the blog
也可以看看:
  • Display dynamic image from database or remote source with p:graphicImage and StreamedContent
  • 09-25 21:47