我在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。也可以看看: