在<ui:repeat>中的<p:graphicImage>中显示数据库blob图像

我在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)streamdynamic资源错误。

这是如何造成的,我该如何解决?

您需要认识到, <p:graphicImage>实际上只呈现一个<img src>元素,而后者将在网页浏览器正在parsing所获得的HTML标记并呈现结果时单独调用该URL。

所以,无论你在<p:graphicImage>的getter方法中做什么,都必须这样devise,以便可以在每个请求的基础上调用它。 所以,最合理的方法是用<f:param>创build一个<p:graphicImage> ,其中<p:graphicImage value>指向一个完全独立的请求或应用程序作用域bean, <f:param value>指向独特的图像标识。

例如

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

Images backing 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或更新的版本 ,那么可以考虑使用它的<o:graphicImage>而不是像预期的那样直观地使用它。 另见关于这个主题的博客 。

也可以看看:

  • 使用p:graphicImage和StreamedContent显示来自数据库的dynamic图像

我不明白你为什么需要这个。 您可以创build一个servlet,从映射“http://img.dovov.comyourimage.jpg”的数据库中获取映像。;

这里有一个快速的教程,其中有相应的代码,如何做到这一点。

JSF – 在JSF中显示来自数据库的图像

感谢BalusC。 我通过在backing bean中定义一个整数,并在为图像更新ByteArray时为其分配一个不同的值来做到这一点。 这个整数作为图像的唯一标识符。 然后我把这个整数设置为<p:graphicImage><f:param>值。

图像标签看起来像

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

并将后台bean中的图像设置为

  if(user.getPicture()!=null){ imageId = (int) new Date().getTime(); BinaryStreamImpl bs = new BinaryStreamImpl(user.getPicture()); //picture is byte[] property in user class this.image = new DefaultStreamedContent(bs.getInputStream(), "image/png"); } 

它现在运作良好。

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

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

尝试加载blob到一个字节数组,然后这可能会开始工作。

编辑:看到我的下面的答案这个类似的问题。 graphicimage不在Primefaces中呈现stream式内容

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

在jsf页面;

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

嗯,我99%确定<p:graphicImage与ui <p:graphicImage工作:重复你会有很多问题(因为我做了XD),我build议你创build一个servlet并提供图像作为inputstream(有那里有很多例子)。