如何在 p:dataTable 中使用带有 StreamedContent 的 p:graphicImage? [英] How to use p:graphicImage with StreamedContent within p:dataTable?

查看:24
本文介绍了如何在 p:dataTable 中使用带有 StreamedContent 的 p:graphicImage?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从带有 PrimeFaces 数据表的数据库中动态加载图像.代码如下所示,基于 this PF论坛主题:

I want to dynamically load images from a database withing a PrimeFaces data table. Code looks like as follows which is based on this PF forum topic:

<p:dataTable id="tablaInventario" var="inv" value="#{registrarPedidoController.inventarioList}" paginator="true" rows="10"
    selection="#{registrarPedidoController.inventarioSelected}" selectionMode="single"                                     
    update="tablaInventario tablaDetalle total totalDesc" dblClickSelect="false" paginatorPosition="bottom">
    <p:column sortBy="producto.codigo" filterBy="producto.codigo">
        <f:facet name="header">#{msg.codigo}</f:facet>
        #{inv.producto.codProducto}
    </p:column>                            
    <p:column>
        <f:facet name="header">Foto</f:facet>
        <p:graphicImage id="photo" value="#{registrarPedidoController.streamedImageById}" cache="FALSE">
            <f:param name="inv" value="#{inv.id}" />
        </p:graphicImage>                                
    </p:column>
</p:dataTable>

public StreamedContent getStreamedImageById() {
    DefaultStreamedContent image = null;
    String get = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("inv");
    System.out.println("[Param]: " + get); // This prints null.
    Long id = new Long(get);
    List<Inventario> listInventarios = controladorRegistrarPedido.listInventarios();

    for (Inventario i : listInventarios) {
        if (i.getId().compareTo(id) == 0) {
            byte[] foto = i.getProducto().getFoto();
            image = new DefaultStreamedContent(new ByteArrayInputStream(foto), "image/png");
        }
    }

    return image;
}

但是我无法让它工作.我的参数将null"传递给我的支持 bean.这是怎么引起的,我该如何解决?

However I can't get it work. My param is passing "null" to my backing bean. How is this caused and how can I solve it?

我使用的是 Netbeans 6.9.1、JSF 2.0 和 Primefaces 2.2.RC2.

I am using Netbeans 6.9.1, JSF 2.0 and Primefaces 2.2.RC2.

我继续使用 BalusC 第一个解决方案,它工作正常,但图像没有在 UI 中呈现.Glassfish 抛出异常:

I went on using BalusC first solution, it worked fine but images aren't being rendered in the UI. Exceptions Glassfish is throwing up:

WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
        at com.sun.faces.mgbean.BeanManager$ScopeManager$ViewScopeHandler.isInScope(BeanManager.java:552)

好吧,多亏了 BalusC,我才能开始工作.我已经使用 RequestScoped、SessionScoped 或 ApplicationScoped 来管理 getStreamedImageId.然而,在 UI 中总是设置默认图像(对于 null 情况),而不是与每一行对应的图像.新代码是:

Well seems I get working thanks to BalusC. I've to used RequestScoped, SessionScoped or ApplicationScoped for managing the getStreamedImageId. However in the UI is always setting the default image (for the null cases) and not as expected the image that correspondes to each row. The new code is:

public StreamedContent streamedById(Long id) {
    DefaultStreamedContent image = null;

    System.out.println("[ID inventario]: " + id);

    List<Inventario> listInventarios = controladorRegistrarPedido.listInventarios();
    for (Inventario i : listInventarios) {
        if (i.getId().equals(id)) {
            byte[] foto = i.getProducto().getFoto();
            if (foto != null) {
                System.out.println("   [Foto]: " + foto);
                image = new DefaultStreamedContent(new ByteArrayInputStream(foto), "image/png");
                break;
            }
        }


    }
    if (image == null) {
        System.out.println("       [Image null]");
        byte[] foto = listInventarios.get(0).getProducto().getFoto();
        image = new DefaultStreamedContent(new ByteArrayInputStream(foto), "image/png");
    }

    System.out.println("   [Foto Streamed]: " + image);

    return image;

}

推荐答案

将调用 getter 方法两次.第一次是将 元素呈现为 HTML,因此需要 src 属性中的 URL.如果您只返回 new DefaultStreamedContent(),那么它会在 src 属性中自动生成正确的 URL.第二次是浏览器真正请求图片的时候,这个时候你应该返回实际的图片.

The <p:graphicImage> will call the getter method twice. First time is when the <img> element is to be rendered to HTML and thus requires an URL in the src attribute. If you just return new DefaultStreamedContent(), then it will autogenerate the right URL in src attribute. Second time is when the browser really requests the image, this is the moment when you should return the actual image.

所以,getter 方法应该基本上是这样的:

So, the getter method should basically look like this:

public StreamedContent getStreamedImageById() {
    FacesContext context = FacesContext.getCurrentInstance();

    if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
        // So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
        return new DefaultStreamedContent();
    }
    else {
        // So, browser is requesting the image. Get ID value from actual request param.
        String id = context.getExternalContext().getRequestParameterMap().get("id");
        Image image = service.find(Long.valueOf(id));
        return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
    }
}

这篇关于如何在 p:dataTable 中使用带有 StreamedContent 的 p:graphicImage?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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