Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Exibindo imagens do banco de dados MySQL na tabela de dados JSF


Você pode usar <p:graphicImage> para exibir imagens armazenadas em um byte[] , independentemente do byte[] fonte (DB, sistema de arquivos em disco, rede, etc). O exemplo mais simples é:
<p:graphicImage value="#{bean.streamedContent}" />

que se refere a um StreamedContent propriedade.

No entanto, isso tem uma armadilha, principalmente quando usado em um componente de iteração, como uma tabela de dados:o método getter será invocado duas vezes; pela primeira vez pelo próprio JSF para gerar a URL para <img src> e a segunda vez pelo navegador da web quando precisar baixar o conteúdo da imagem com base na URL em <img src> . Para ser eficiente, você não deve atingir o DB na primeira chamada de getter. Além disso, para parametrizar a chamada do método getter para que você possa usar um método genérico no qual você passa um ID de imagem específico, você deve usar um <f:param> (observe que o recurso EL 2.2 de passar argumentos de método não funcionará, pois isso não termina na URL de <img src> !).

Resumido, isso deve fazer:
<p:dataTable value="#{bean.items}" var="item">
    <p:column>
        <p:graphicImage value="#{imageStreamer.image}">
            <f:param name="id" value="#{item.imageId}" />
        </p:graphicImage>
    </p:column>
</p:dataTable>

O #{item.imageId} obviamente retorna o identificador exclusivo da imagem no banco de dados (a chave primária) e, portanto, não o byte[] contente. O #{imageStreamer} é um bean com escopo de aplicativo que se parece com isso:
@ManagedBean
@ApplicationScoped
public class ImageStreamer {

    @EJB
    private ImageService service;

    public StreamedContent getImage() throws IOException {
        FacesContext context = FacesContext.getCurrentInstance();

        if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            // So, we're rendering the HTML. 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 imageId = context.getExternalContext().getRequestParameterMap().get("imageId");
            Image image = imageService.find(Long.valueOf(imageId));
            return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
        }
    }

}

A Image class é neste exemplo em particular apenas um @Entity com um @Lob em bytes propriedade (como você está usando JSF, é claro que assumo que você está usando JPA para interagir com o banco de dados).
@Entity
public class Image {

    @Id
    @GeneratedValue(strategy = IDENTITY) // Depending on your DB, of course.
    private Long id;

    @Lob
    private byte[] bytes;

    // ...
}

O ImageService é apenas um padrão @Stateless EJB, nada de especial para ver aqui:
@Stateless
public class ImageService {

    @PersistenceContext
    private EntityManager em;

    public Image find(Long id) {
        return em.find(Image.class, id);
    }

}

Veja também: