# Bilder aus Datenbank dynamisch in JSF streamen



## norm (27. Okt 2011)

Hallo Community,

ich bin relativ neu in der JSF-Welt, habe baer schon eingie Erfahrung im Bereich Java EE.

Ich hänge nun an foolgendem Use-Case:

Eine Bean liefert eine Collection mit einer unbekannten Anzahl von Image-Objekten (selbstdefinierter Datentyp) via JPA aus einer Postgres-Datenbank. 
Diese Image-Objekte enthalten byte-Arrays, die die eigentlichen Bilder repräsentieren.
Nun brauche ich eine JSF-Seite die dynamisch diese Bilder anzeigen kann, also für eine unbestimmte Anzahl von Bildern.

Zum anzeigen der Bilder kommen ja PrimeFaces in Frage:
[XML]<p:graphicImage value="#{dynamicImageController.chart}" />[/XML]

Kann ich in einem JSF über eine Collection iterieren und dann für jedes Objekt so ein graphicImage-Tag erzeugen?

Gruß


----------



## norm (27. Okt 2011)

Vielleicht habe ich mich zu kompliziert ausgedrückt:

Ist es möglich ein Bild im JSF anzuzeigen, ohne dass dieses Bild als File im Dateisystem vorliegt?


----------



## maki (27. Okt 2011)

Brauchst imho ein "Stream Servlet". k.A: ob primefaces da was fertiges bietet.

http://www.java-forum.org/web-tier/90649-jsf-darstellen-blob-datentypen.html


----------



## JimPanse (27. Okt 2011)

oder meintest so was:

```
<c:forEach items="#{dynamicImageController.charts}" var="chart">
             <p:graphicImage value="#{chart}" />
</c:forEach>
```

Wenn ich mir das PrimeFaces BSP anschaue müsstest du anstatt


```
private StreamedContent chart;
```
eine list haben:

```
private List<StreamedContent> charts;
```

oder sollen die Bilder (byte[]) erst beim aufruf der Seite umgewandelt werden???


----------



## norm (27. Okt 2011)

JimPanse hat gesagt.:


> oder meintest so was:
> 
> ```
> <c:forEach items="#{dynamicImageController.charts}" var="chart">
> ...



Also so wie es da oben steht, habe ich es versucht! Die Bilder liegen ja schon als BLOBS in der DB vor.
Leider scheint es mit dem graphicImage Tag nicht zu gehen, da dieses als Value nur einen pfad zu der datei im dateisystem entgegennimmt.

meine recherchen zum thema stream servlet sind im sande verlaufen, vielleicht fehlt mir das allgemeine verständnis zu servlets?! :bahnhof:

RichFaces bekomme ich nicht zum laufen auf dem glassfish.... :bahnhof:

wundert mich dass das so kompliziert ist, ist doch nicht mehr so ungewöhnlich bilder in dbs zu speichern, oder? ich würde es ja auch im filesystem machen aber mir sind diesbezüglich mehr oder weniger die hände gebunden...


----------



## JimPanse (27. Okt 2011)

Du kannst dir auch ein eigenes Tag schreiben was das byte feld entgegen nimmt und als Bild rausschreibt.

s.h. Diskussion im IceFaces Forum:

How to display a dynamic image from blob data


----------



## norm (2. Nov 2011)

Hallo Mädels,

ich habe es nun mit PrimeFaces gelöst:

Das Facelet enthält:
[XML]
<p:graphicImage value="#{ImageLoader.content}" title="aImage" alt="Image Test!"/>
[/XML]

Dazugehörige Bean:

```
@Named(value="ImageLoader")
@Stateless
public class ImageLoader {
    
    @Inject
    private ImageFacade imgFacade;
    
    private StreamedContent content;

    public StreamedContent getContent() {
        return content;
    }

    public void setContent(StreamedContent content) {
        this.content = content;
    }
    
    @PostConstruct
    public void loadImage(){
        //JPA-Aufruf
        List<Image> findAll = imgFacade.findAll();
        //1. Bild laden
        byte[] imagedata = findAll.get(0).getImagedata();
        content = new DefaultStreamedContent(new ByteArrayInputStream(imagedata), "image/jpeg");
    }
}
```

Gruß und danke!


----------



## norm (3. Nov 2011)

Hallo Community,

ich nochmal!

Also wie gesagt, dass anzeigen eines einzelnen Bildes funktioniert nun.
Aber leider funktioniert das iterieren über eine Collection aus Bildern nicht.

Ich habe sowohl

[XML]
<ui:repeat value="#{ImageLoader.allImages}" var="image">
                    <p:graphicImage value="#{image}" alt="Hier sollte ein Bild sein" />
                    <br/>
                </ui:repeat>
[/XML]

als auch

[XML]
<c:forEach items="#{ImageLoader.allImages}" var="image">
                    <p:graphicImage value="#{image}" alt="Hier sollte ein Bild sein" />
                    <br/>
</c:forEach>
[/XML]

ausprobiert. Bei der forEach Variante wird der Getter von allImages in einer Endlosschleife aufgerufen, bei der repeat Variante wird nur der Alternativtext ausgegeben...

Die zugehörige Bean sieht so aus:


```
@Named(value = "ImageLoader")
@Stateless
public class ImageLoader {

    @Inject
    private ImageFacade imgFacade;
    
    private List<StreamedContent> allImages = new ArrayList <>();
    
    private StreamedContent oneImage;

    public StreamedContent getOneImage() {
        List<Image> findAll = imgFacade.findAll();
        byte[] imagedata = findAll.get(0).getImagedata();
        StreamedContent retVal = new DefaultStreamedContent(new ByteArrayInputStream(imagedata));
        return retVal;
    }

    public void setOneImage(StreamedContent oneImage) {
        this.oneImage = oneImage;
    }

    public List<StreamedContent> getAllImages() {
        List<Image> findAll = imgFacade.findAll();
        Logger.getLogger(ImageLoader.class.getName()).log(Level.INFO, "### COUNT: {0}", findAll.size());
        for (Image image : findAll) {
            byte[] imagedata = image.getImagedata();
            allImages.add(new DefaultStreamedContent(new ByteArrayInputStream(imagedata)));
            Logger.getLogger(ImageLoader.class.getName()).log(Level.INFO, "### Added Image {0}", image.getImagename());
        }
        return allImages;
    }

    public void setAllImages(ArrayList<StreamedContent> allImages) {
        this.allImages = allImages;
    }
}
```

Sieht jemand das Problem?

Gruß


----------

