我想使用PrimeFaces数据表从数据库动态加载图像。代码如下所示,基于this PF forum topic:
<p:dataTable id="tablaInventario" var="inv" value="#{registrarPedidoController.inventarioList}" paginator="true" rows="10"
selection="#{registrarPedidoController.inventarioSelected}" selectionMode="single"
update="tablaInventario tablaDetalle total totalDesc" dblClickSelect="false" paginatorPosition="bottom">
<p:column sortBy="producto.codigo" filterBy="producto.codigo">
<f:facet name="header">#{msg.codigo}</f:facet>
#{inv.producto.codProducto}
</p:column>
<p:column>
<f:facet name="header">Foto</f:facet>
<p:graphicImage id="photo" value="#{registrarPedidoController.streamedImageById}" cache="FALSE">
<f:param name="inv" value="#{inv.id}" />
</p:graphicImage>
</p:column>
</p:dataTable>
与
public StreamedContent getStreamedImageById() {
DefaultStreamedContent image = null;
String get = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("inv");
System.out.println("[Param]: " + get); // This prints null.
Long id = new Long(get);
List<Inventario> listInventarios = controladorRegistrarPedido.listInventarios();
for (Inventario i : listInventarios) {
if (i.getId().compareTo(id) == 0) {
byte[] foto = i.getProducto().getFoto();
image = new DefaultStreamedContent(new ByteArrayInputStream(foto), "image/png");
}
}
return image;
}
但是我无法让它发挥作用。我的参数将“null”传递给我的支持bean。这是怎么造成的,我该如何解决?
我正在使用Netbeans 6.9.1,JSF 2.0和Primefaces 2.2.RC2。
我继续使用BalusC第一个解决方案,它工作正常,但图像没有在UI中呈现。例外Glassfish正在呕吐:
WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
at com.sun.faces.mgbean.BeanManager$ScopeManager$ViewScopeHandler.isInScope(BeanManager.java:552)
感谢BalusC,我似乎得到了工作。我将使用RequestScoped,SessionScoped或ApplicationScoped来管理getStreamedImageId。但是,在UI中始终设置默认图像(对于空的情况)而不是预期的与每行对应的图像。新代码是:
public StreamedContent streamedById(Long id) {
DefaultStreamedContent image = null;
System.out.println("[ID inventario]: " + id);
List<Inventario> listInventarios = controladorRegistrarPedido.listInventarios();
for (Inventario i : listInventarios) {
if (i.getId().equals(id)) {
byte[] foto = i.getProducto().getFoto();
if (foto != null) {
System.out.println(" [Foto]: " + foto);
image = new DefaultStreamedContent(new ByteArrayInputStream(foto), "image/png");
break;
}
}
}
if (image == null) {
System.out.println(" [Image null]");
byte[] foto = listInventarios.get(0).getProducto().getFoto();
image = new DefaultStreamedContent(new ByteArrayInputStream(foto), "image/png");
}
System.out.println(" [Foto Streamed]: " + image);
return image;
}
答案 0 :(得分:33)
<p:graphicImage>
将两次调用getter方法。第一次是将<img>
元素呈现为HTML,因此需要src
属性中的URL。如果您只是返回new DefaultStreamedContent()
,那么它会在src
属性中自动生成正确的网址。第二次是浏览器真正请求图像时,这是您应该返回实际图像的时刻。
所以,getter方法基本上应该是这样的:
public StreamedContent getStreamedImageById() {
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. Get ID value from actual request param.
String id = context.getExternalContext().getRequestParameterMap().get("id");
Image image = service.find(Long.valueOf(id));
return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
}
}
答案 1 :(得分:3)
如果我们通过休眠保存它们,图像将作为byte []保存在数据库中。我使用<p:fileUpload
...标签上传了图像,然后使用hibernate将图像与其他数据值一起保存。
在第二页上,我正在使用
显示整个表格数据(当然还有图像)<p:dataTable var="data" value="#{three.all}" ....
和使用
的动态图像<p:graphicImage alt="image" value="#{three.getImage(data)}" cache="false" >
<f:param id="image_id" name="image_id" value="#{data.number}" />
</p:graphicImage></p:dataTable>
这里“三”是Backing Bean的名称。在方法getAll()
中,我正在通过hibernate从表中检索数据,并且在同一方法中,我创建了一个HashMap<Integer, byte[]>
。 HashMap是bean的实例变量,Bean是SessionScoped。我将images
(以byte[]
形式)与整数image_id放在一起。
代码:
for (int i=0; i<utlst.size(); i++ ){
images.put(utlst.get(i).getNumber(), utlst.get(i).getImage());}
//utlst is the object retrieved from database. number is user-id.
在视图getImage.xhtml中,<p:graphicImage alt="image" value="#{three.getImage(data)}" cache="false" >
调用方法getImage(data /*I am passing current object of the list which is being iterated by
*/ )
getImage的代码:
public StreamedContent getImage(Util ut) throws IOException {
//Util is the pojo
String image_id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("image_id");
System.out.println("image_id: " + image_id);
if (image_id == null) {
defaultImage=new DefaultStreamedContent(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/Capture.PNG"), "image/png");
return defaultImage;
}
image= new DefaultStreamedContent(new ByteArrayInputStream(images.get(Integer.valueOf(image_id))), "image/png");
return image;
}
只需在会话中使用A HashMap中的ID保存动态图像,然后就可以正确地对其进行流式处理。
谢谢&amp;问候, Zeeshan
答案 2 :(得分:2)
在PrimeFaces 3.2中,错误仍然存在。我用
做了解决方法<p:graphicImage value="#{company.charting}">
<f:param id="a" name="a" value="#{cc.attrs.a}" />
<f:param id="b" name="b" value="#{cc.attrs.b}" />
</p:graphicImage>
和
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
String a= externalContext.getRequestParameterMap().get("a");
String b= externalContext.getRequestParameterMap().get("b");
但即便如此,豆子被召唤2次。但是在第二个调用变量a + b被填充; - )
该死的bug