从JSF datatable中的MySQL数据库显示图像 [英] Displaying images from MySQL database in JSF datatable

查看:119
本文介绍了从JSF datatable中的MySQL数据库显示图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MySQL数据库存储图像在一个 blob 列。我想在PrimeFaces < p:dataTable> 中显示它们。如何实现?

解决方案

您可以使用 < p:graphicImage> 显示存储在字节[ ] ,而不管 byte [] source(DB,磁盘文件系统,网络等)。最简单的例子是:

 < p:graphicImage value =#{bean.streamedContent} /> 

它引用了一个 StreamedContent 属性。 p>

然而,这是一个陷阱,特别是在诸如数据表的迭代组件中使用时:getter方法将被调用两次;第一次由JSF自己生成< img src> 的URL,第二次由webbrowser在需要根据< img src> 。为了有效率,您不应该在第一个getter调用中击中DB。另外,要参数化getter方法调用,以便您可以使用通用特定图像ID的通用方法,您应该使用< f:param> (请请注意,传递方法参数的EL 2.2功能将无法正常工作,因为这不会导致< img src> !的URL)。



总结说,这应该是:

  p:dataTable value =#{bean.items}var =item> 
< p:column>
< p:graphicImage value =#{imageStreamer.image}>
< f:param name =idvalue =#{item.imageId}/>
< / p:graphicImage>
< / p:column>
< / p:dataTable>

#{item.imageId} 返回数据库(主键)中图像的唯一idenfitier,因此 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){
//所以,我们渲染HTML。返回一个存根StreamedContent,以便它将生成正确的URL。
返回新的DefaultStreamedContent();
} else {
//所以浏览器正在请求图像。用图像字节返回一个真正的StreamedContent。
String imageId = context.getExternalContext()。getRequestParameterMap()。get(imageId);
Image image = imageService.find(Long.valueOf(imageId));
返回新的DefaultStreamedContent(新的ByteArrayInputStream(image.getBytes()));
}
}

}

code> Image class在这个特殊的例子中只有一个 @Entity @Lob 字节属性(因为你使用JSF,我的cource假定你正在使用JPA与数据库进行交互)。

  @Entity 
public class Image {

@Id
@ GeneratedValue(strategy = IDENTITY)//根据您的DB,当然。
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);
}

}



另请参见:




I have MySQL database which stores images in a blob column. I would like to show them in a PrimeFaces <p:dataTable>. How can I achieve this?

解决方案

You can use <p:graphicImage> to display images stored in a byte[], regardless of the byte[] source (DB, disk file system, network, etc). Simplest example is:

<p:graphicImage value="#{bean.streamedContent}" />

which refers a StreamedContent property.

This has however a pitfall, particularly when used in an iterating component such as a data table: the getter method will be invoked twice; the first time by JSF itself to generate the URL for <img src> and the second time by webbrowser when it needs to download the image content based on the URL in <img src>. To be efficient, you should not be hitting the DB in the first getter call. Also, to parameterize the getter method call so that you can use a generic method wherein you pass a specific image ID, you should be using a <f:param> (please note that EL 2.2 feature of passing method arguments won't work at all as this doesn't end up in URL of <img src>!).

Summarized, this should do:

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

The #{item.imageId} obviously returns the unique idenfitier of the image in the DB (the primary key) and thus not the byte[] content. The #{imageStreamer} is an application scoped bean which look like this:

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

}

The Image class is in this particular example just an @Entity with a @Lob on bytes property (as you're using JSF, I of cource assume that you're using JPA to interact with the DB).

@Entity
public class Image {

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

    @Lob
    private byte[] bytes;

    // ...
}

The ImageService is just a standard @Stateless EJB, nothing special to see here:

@Stateless
public class ImageService {

    @PersistenceContext
    private EntityManager em;

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

}

See also:

这篇关于从JSF datatable中的MySQL数据库显示图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆