在<pi:graphicimage>里面显示数据库blob图像<ui:repeat> </ui:repeat> </p:graphicimage>

时间:2012-04-09 13:26:36

标签: jsf primefaces dynamic-content uirepeat graphicimage

我在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中遇到以下错误:

  

SEVERE [org.primefaces.application.PrimeResourceHandler](http - 127.0.0.1-8080-12)流式动态资源出错。

这是如何引起的?如何解决?

6 个答案:

答案 0 :(得分:54)

您需要意识到<p:graphicImage>实际上仅使用一个URL呈现<img src>元素,然后当Web浏览器即将解析获取的HTML标记并显示结果时,该URL将被Web浏览器单独调用。

因此,无论您在<p:graphicImage>的getter方法中执行什么操作,都必须将其设计为可以基于每个请求调用它。因此,最理智的方法是使用<p:graphicImage>创建<f:param>,其中<p:graphicImage value>指向一个完全独立的请求或应用程序范围的bean,<f:param value>指向唯一的图像标识符

E.g。

<p:graphicImage value="#{images.image}">
    <f:param name="id" value="#{someBean.imageId}" />
</p:graphicImage>

Images支持bean看起来像这样:

@ManagedBean
@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

另见:

答案 1 :(得分:3)

我不明白为什么你需要这个。您可以创建一个servlet,它将使用映射&#34; /images/yourimage.jpg"从数据库中获取图像。

这是一个快速教程,其中包含有关如何执行此操作的相应代码。

JSF - Displaying images from database in JSF

答案 2 :(得分:3)

感谢BalusC。我通过在backing bean中定义一个整数并在更新图像的ByteArray时为其分配一个diffent值来做到这一点。该整数用作图像的唯一标识符。然后我在页面上的int *a = new int[10]; a++; delete a; 内将此整数设置为<f:param>的值。

图片标签看起来像

<p:graphicImage>

并将支持bean中的图像设置为

 <p:graphicImage value="#{empBean.image}">
    <f:param name="id" value="#{empBean.imageId}" />
  </p:graphicImage>`

它现在很好用。

答案 3 :(得分:1)

您必须牢记graphicImage组件在页面上呈现的内容。它呈现为HTML <img>元素。在浏览器中,将为JSF页面发出请求,然后对页面上的每个图像也会发出后续请求。

这些图像来自PrimeFaces资源servlet而不是FacesServlet,这意味着Managed Bean的范围及其属性可能不适用。

首先尝试将blob加载到字节数组中,然后这可能会开始工作。

编辑:请参阅我对此类似问题的以下回答。 graphicimage not rendering streamedcontent in Primefaces

答案 4 :(得分:0)

InputStream is = new ByteArrayInputStream((byte[]) yourBlobData);
myImage = new DefaultStreamedContent(is, "image/png");

在jsf页面中;

<p:graphicImage value="#{controller.myImage}" style="width:200px;width:500px" />

答案 5 :(得分:-2)

mmm我99%确定<p:graphicImage无法使用ui:重复你会遇到很多问题(因为我做了XD),我建议你创建一个servlet并将图像作为输入流提供(那里有很多例子)。