Подтвердить что ты не робот

Как использовать p: graphicImage с StreamedContent в p: dataTable?

Я хочу динамически загружать изображения из базы данных с помощью таблицы данных PrimeFaces. Код выглядит следующим образом, который основан на этой теме форума PF:

<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. Как это вызвано и как я могу его решить?

Я использую Netbeans 6.9.1, JSF 2.0 и Primefaces 2.2.RC2.

Я продолжал использовать первое решение BalusC, он работал нормально, но изображения не отображаются в пользовательском интерфейсе. Исключения Glassfish вздымается:

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. Однако в пользовательском интерфейсе всегда задается образ по умолчанию (для нулевых случаев), а не как ожидалось, изображение, соответствующее каждой строке. Новый код:

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;

}
4b9b3361

Ответ 1

<p:graphicImage> дважды вызовет метод геттера. Первый раз, когда элемент <img> должен быть отображен в HTML и, следовательно, требует URL-адреса в атрибуте src. Если вы просто вернете new DefaultStreamedContent(), тогда он будет автогенерировать правильный URL-адрес в атрибуте src. Второй раз, когда браузер действительно запрашивает изображение, это тот момент, когда вы должны вернуть фактическое изображение.

Итак, метод getter должен выглядеть следующим образом:

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

Ответ 2

изображения сохраняются в базе данных как byte [], если мы сохраняем их через спящий режим. Я загрузил изображения с тегом <p:fileUpload..., затем сохраняю изображение вместе с другими значениями данных, используя спящий режим.

На второй странице я показываю все данные таблицы (конечно, с изображениями), используя

<p:dataTable  var="data" value="#{three.all}" ....

и динамических изображений с использованием

<p:graphicImage   alt="image"  value="#{three.getImage(data)}" cache="false"  >
                <f:param id="image_id" name="image_id" value="#{data.number}" />
</p:graphicImage></p:dataTable>

Здесь "three" - это имя Backing Bean. В методе getAll() я извлекаю данные из таблицы через спящий режим и в том же методе, я создал HashMap<Integer, byte[]>. HashMap - это переменная экземпляра bean, а bean - SessionScoped. Я помещаю images (которые находятся в форме byte[]) вместе с целым image_id.

код:

    for (int i=0; i<utlst.size(); i++ ){
             images.put(utlst.get(i).getNumber(), utlst.get(i).getImage());}
//utlst is the object retrieved from database. number is user-id.

В представлении getImage.xhtml, <p:graphicImage alt="image" value="#{three.getImage(data)}" cache="false" > он вызывает метод getImage(data /*I am passing current object of the list which is being iterated by */ )

код getImage:

public StreamedContent getImage(Util ut) throws IOException {
       //Util is the pojo

          String image_id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("image_id");
          System.out.println("image_id: " + image_id);

          if (image_id == null) {

                defaultImage=new DefaultStreamedContent(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/Capture.PNG"), "image/png");

            return defaultImage; 
        }


         image= new DefaultStreamedContent(new ByteArrayInputStream(images.get(Integer.valueOf(image_id))), "image/png");

        return image;
    }

просто держите свои динамические изображения с идентификаторами в AHashMap в сеансе, тогда они будут правильно переданы.

Спасибо и приветствую, Zeeshan

Ответ 3

В PrimeFaces 3.2 ошибка все еще присутствует. Я делаю обходной путь с помощью

<p:graphicImage value="#{company.charting}">
    <f:param id="a" name="a" value="#{cc.attrs.a}" />
    <f:param id="b" name="b" value="#{cc.attrs.b}" />
</p:graphicImage>

и

ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
String a= externalContext.getRequestParameterMap().get("a");
String b= externalContext.getRequestParameterMap().get("b");

Но даже с этим bean вызывается 2 раза. Но во второй переменной вызова a + b заполняется; -)

Проклятая ошибка