4

我有 MySQL 数据库,它将图像存储在一个blob列中。我想在 PrimeFaces 中展示它们<p:dataTable>。我怎样才能做到这一点?

4

2 回答 2

12

无论来源如何(数据库、磁盘文件系统、网络等),您都可以使用它<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带有@Lobonbytes属性的类(当您使用 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只是一个标准的@StatelessEJB,这里没什么特别的:

@Stateless
public class ImageService {

    @PersistenceContext
    private EntityManager em;

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

}

也可以看看:

于 2013-06-05T13:13:27.300 回答
-1

如果您使用的是 Richfaces,则可以使用a4j:mediaOutput组件从 bean 流式传输 blob。

如果不是这样,恐怕我对 Primefaces 不熟悉。如果它没有为此提供任何组件,则您需要一种生成指向返回 blob 的 servlet 的 URL 的方法。这样您就可以使用h:graphicImage该自动生成的 URL。

于 2013-06-05T08:28:57.277 回答