在<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(有那里有很多例子)。