Anda dapat menggunakan <p:graphicImage>
untuk menampilkan gambar yang disimpan dalam byte[]
, terlepas dari byte[]
sumber (DB, sistem file disk, jaringan, dll). Contoh paling sederhana adalah:
<p:graphicImage value="#{bean.streamedContent}" />
yang merujuk pada StreamedContent
properti.
Namun ini memiliki jebakan, terutama ketika digunakan dalam komponen iterasi seperti tabel data:metode pengambil akan dipanggil dua kali; pertama kali oleh JSF sendiri untuk menghasilkan URL untuk <img src>
dan kedua kalinya oleh browser web ketika perlu mengunduh konten gambar berdasarkan URL di <img src>
. Agar efisien, Anda tidak boleh menekan DB pada panggilan pengambil pertama. Selain itu, untuk membuat parameter pemanggilan metode pengambil sehingga Anda dapat menggunakan metode umum tempat Anda meneruskan ID gambar tertentu, Anda harus menggunakan <f:param>
(harap perhatikan bahwa fitur EL 2.2 dari argumen metode yang lewat tidak akan berfungsi sama sekali karena ini tidak berakhir di URL <img src>
!).
Ringkasnya, ini harus dilakukan:
<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>
#{item.imageId}
jelas mengembalikan pengidentifikasi unik gambar di DB (kunci utama) dan dengan demikian tidak byte[]
isi. #{imageStreamer}
adalah kacang cakupan aplikasi yang terlihat seperti ini:
@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()));
}
}
}
Image
kelas dalam contoh khusus ini hanyalah sebuah @Entity
dengan @Lob
pada bytes
property (karena Anda menggunakan JSF, tentu saja saya berasumsi bahwa Anda menggunakan JPA untuk berinteraksi dengan DB).
@Entity
public class Image {
@Id
@GeneratedValue(strategy = IDENTITY) // Depending on your DB, of course.
private Long id;
@Lob
private byte[] bytes;
// ...
}
ImageService
hanyalah @Stateless
standard standar EJB, tidak ada yang istimewa untuk dilihat di sini:
@Stateless
public class ImageService {
@PersistenceContext
private EntityManager em;
public Image find(Long id) {
return em.find(Image.class, id);
}
}