Como usar p: graphicImage com StreamedContent dentro de p: dataTable?

Eu quero carregar dinamicamente imagens de um database dentro de uma tabela de dados PrimeFaces. O código se parece com o seguinte, baseado neste tópico do fórum de FP :

#{msg.codigo} #{inv.producto.codProducto}

Foto

com

 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 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; } 

No entanto, não consigo trabalhar. Meu param está passando “null” para o meu bean de apoio. Como isso é causado e como posso resolvê-lo?

Eu estou usando o NetBeans 6.9.1, JSF 2.0 e Primefaces 2.2.RC2.

Eu continuei usando a primeira solução da BalusC, funcionou bem, mas as imagens não estão sendo renderizadas na interface do usuário. Exceções Glassfish está vomitando:

 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) 

Bem, parece que eu trabalho graças ao BalusC. Eu usei RequestScoped, SessionScoped ou ApplicationScoped para gerenciar o getStreamedImageId. No entanto, na interface do usuário é sempre definir a imagem padrão (para os casos nulos) e não como esperado a imagem que corresponde a cada linha. O novo código é:

 public StreamedContent streamedById(Long id) { DefaultStreamedContent image = null; System.out.println("[ID inventario]: " + id); List 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; } 

O chamará o método getter duas vezes. A primeira vez é quando o elemento é renderizado para HTML e, portanto, requer uma URL no atributo src . Se você acabou de retornar o new DefaultStreamedContent() , ele gerará automaticamente o URL correto no atributo src . A segunda vez é quando o navegador realmente solicita a imagem, esse é o momento em que você deve retornar a imagem real.

Então, o método getter deve basicamente se parecer com isto:

 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())); } } 

as imagens são salvas no database como byte [] se forem salvas no modo de hibernação. as imagens com a tag ... e a imagem junto com outros valores de dados usando o modo de hibernação.

Na segunda página, estou exibindo os dados da tabela inteira (claro que com imagens) usando

  

e imagens dinâmicas usando

    

Aqui "três" é o nome do Backing Bean. No método getAll() , estou recuperando dados da tabela através do hibernate e no mesmo método, criei um HashMap . HashMap é uma variável de instância do bean e The Bean is SessionScoped. Estou colocando as images (que estão na forma byte[] ) junto com um inteiro image_id.

código:

  for (int i=0; i 

Na vista getImage.xhtml, chama o método getImage(data /*I am passing current object of the list which is being iterated by */ )

código de 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; } 

apenas mantenha suas imagens dinâmicas com ids em um hashmap na session e elas serão corretamente transmitidas.

Obrigado e cumprimentos, Zeeshan

No PrimeFaces 3.2 o bug ainda está presente. Eu faço a solução alternativa com

     

e

 ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); String a= externalContext.getRequestParameterMap().get("a"); String b= externalContext.getRequestParameterMap().get("b"); 

Mas mesmo com isso o bean é chamado 2 vezes. Mas na segunda variável de chamada a + b é preenchida 😉

Maldito bug