我有 MySQL 数据库,它将图像存储在一个blob
列中。我想在 PrimeFaces 中展示它们<p:dataTable>
。我怎样才能做到这一点?
2 回答
无论来源如何(数据库、磁盘文件系统、网络等),您都可以使用它<p:graphicImage>
来显示存储在 a 中的图像。最简单的例子是:byte[]
byte[]
<p:graphicImage value="#{bean.streamedContent}" />
它指的是一个StreamedContent
属性。
然而,这有一个缺陷,特别是在用于迭代组件(如数据表)时:getter 方法将被调用两次;第一次由 JSF 自己生成 URL,<img src>
第二次由 webbrowser 需要根据<img src>
. 为了提高效率,您不应该在第一个 getter 调用中访问数据库。此外,要参数化 getter 方法调用,以便您可以使用传递特定图像 ID 的通用方法,您应该使用<f:param>
(请注意,传递方法参数的 EL 2.2 功能根本不起作用,因为这没有' t 以<img src>
!)的 URL 结尾。
总结一下,应该这样做:
<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}
唯一标识符(主键),因此不返回byte[]
内容。这#{imageStreamer}
是一个应用程序范围的 bean,如下所示:
@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
特定的示例中,该类只是一个@Entity
带有@Lob
onbytes
属性的类(当您使用 JSF 时,我当然假设您正在使用 JPA 与 DB 交互)。
@Entity
public class Image {
@Id
@GeneratedValue(strategy = IDENTITY) // Depending on your DB, of course.
private Long id;
@Lob
private byte[] bytes;
// ...
}
这ImageService
只是一个标准的@Stateless
EJB,这里没什么特别的:
@Stateless
public class ImageService {
@PersistenceContext
private EntityManager em;
public Image find(Long id) {
return em.find(Image.class, id);
}
}
也可以看看:
如果您使用的是 Richfaces,则可以使用a4j:mediaOutput组件从 bean 流式传输 blob。
如果不是这样,恐怕我对 Primefaces 不熟悉。如果它没有为此提供任何组件,则您需要一种生成指向返回 blob 的 servlet 的 URL 的方法。这样您就可以使用h:graphicImage
该自动生成的 URL。