我在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)流式动态资源出错。
这是如何引起的?如何解决?
答案 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"从数据库中获取图像。
这是一个快速教程,其中包含有关如何执行此操作的相应代码。
答案 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并将图像作为输入流提供(那里有很多例子)。