# JSF: Darstellen von Blob Datentypen



## janpaet (2. Nov 2009)

Hallo zusammen,
ich finde einfach keinen Weg, um Blob-Datentypen in einer JSF-Seite anzuzeigen.
Vielleicht kann mir ja hier jemand weiterhelfen.

Ich verwende JBoss Seam und MS-SQL-Server.

Ich habe eine Entity-Bean:

```
@Entity
@Name("news")
@Scope(ScopeType.SESSION)
@Table(name="dbo.News")

public class News implements Serializable{

	private static final long serialVersionUID = 1L;

	@Id private String newsDate;
	private String newsMessage;
	private byte[] newsImage;
	
	@Lob @Basic(fetch = FetchType.EAGER)
	public byte[] getNewsImage() {return newsImage;}
	public void setNewsImage(byte[] newsImage) {this.newsImage = newsImage;}

	public String getNewsDate() {return newsDate;}
	public void setNewsDate(String newsDate) {this.newsDate = newsDate;}
	
	public String getNewsMessage() {return newsMessage;}
	public void setNewsMessage(String newsMessage) {this.newsMessage = newsMessage;}
}
```

Ich habe eine Session-Bean:

```
@Stateful
@Name("manager")
@Scope(ScopeType.SESSION)

public class NewsDao implements INewsDao{
	
	@PersistenceContext	
	private EntityManager em;
	
	@DataModel
	private List<News> news;
	
	@Create
	public void find() {
		news = em.createQuery("select n from News n").getResultList()
	}

	public List<News> getNews(){return news;}
	
	@Remove @Destroy
	public void destroy(){}
}
```

und ich habe eine xhtml-Seite

```
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:rich="http://richfaces.org/rich"
      xmlns:a4j="http://richfaces.org/a4j"      
      template="template.xhtml">

      <ui:define name="content">
		
	<h:dataTable value="#{manager.news}" var="myNews" style="width:600px;">
	     <h:column>
		<rich:panel>
		     <f:facet name="header" >
			<h:outputText value="#{myNews.newsSubject}"/>
		     </f:facet>		
			<div class="news">
			     <p class="newsPictureLeft" >
                                      <h:graphicImage value="#{myNews.newsImage}" /> 
                                 </p>
			     <p class="newsMessage">
			          <h:outputText value="#{myNews.newsMessage}" />
			     </p>
			</div>
			</rich:panel>
		 </h:column>
		 <div />
    	     </h:dataTable>		 		 
	</ui:define>
</ui:composition>
```

Was muss ich jetzt tun um in einem h:graphicImage das Attribut newsImage aus der Entity-Bean darzustellen zu können?

Vielen Dank und Grüße
Jan


----------



## maki (2. Nov 2009)

> Was muss ich jetzt tun um in einem h:graphicImage das Attribut newsImage aus der Entity-Bean darzustellen zu können?


Du brauchst ein sog. Stream Servlet.
[c]<h:graphicImage .. />[/c] rendert dir ein [c]<img ../>[/c] Tag mit einer URL, kann aber keinen Blob einfach so in eine  HTML Seite einfügen, sowas ist gar nicht vorgesehen in HTML.


----------



## janpaet (2. Nov 2009)

Hi Maki,
erst mal vielen Dank.

Vielleicht wäre es besser nur den Pfad zum Image in der Datenbank zu speichern und es dann aus dem Dateisysem zu holen, um es dann an den Client zu senden?

Also ungefähr in der Art?

```
try {
			Hashtable env = new Hashtable();
			env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
			Context ctx = new InitialContext(env);
			...
			ctx.close();
		} 
		catch (NamingException e) {
				e.printStackTrace();
		}
```

Viele Grüße
Jan


----------



## maki (2. Nov 2009)

Erzähl doch aml ein bisschen über die Bilder, wie groß sind alle zusammen (<> 4GiB?), wie werden sie erzeugt (falls sie es werden), wie lange werden sie vorgehalten, etc. pp.


----------



## janpaet (2. Nov 2009)

Ok,
der Anwender möchte Nachrichten mit Bildern auf seiner Web-Seite darstellen.
Jetzt möchte ich ihm anbieten, den Text und das Bild in einer Datenbank zu speichern oder das Bild in ein Verzeichnis zu kopieren, von wo es dann in die Web-Anwendung eingelesen wird.

Die Bilder selbst können bestimmt bis zu 1 GB groß werden.
Ich hoffe wir überschneiden uns gerade nicht mit den Antworten, sorry meine Schuld.

Viele Grüße
Jan


----------



## maki (3. Nov 2009)

> Jetzt möchte ich ihm anbieten, den Text und das Bild in einer Datenbank zu speichern oder das Bild in ein Verzeichnis zu kopieren, von wo es dann in die Web-Anwendung eingelesen wird.
> 
> Die Bilder selbst können bestimmt bis zu 1 GB groß werden.


Bei dieser Datenmenge wäre noch beides möglich, hat beides auch Vor- und Nachteile.
Wenn alles in der DB ist, hast du den Vorteil dass deine Daten konsistent bleiben, das ist beim Filesystem nicht immer der Fall, wenn nur die URL in der DB gespeichert wird.


----------



## Deadalus (3. Nov 2009)

Benutzt du Richfaces oder zumindest die a4j Library? Dort gibt es eine Komponente, mit der du sehr leicht byte[] Bilder darstellen kannst. 

Das Ganze sieht dann ungefähr so aus: 
In der JSF Seite

<a4j:mediaOutput  element="img"  value="#{Bean.wert}"
                                        createContent="#{Bean.paintBild}" mimeType="image/jpeg"/>

Bean.wert sollte eine Wert, sein mit dem du in der Paint Methode das Bild identifizieren kannst, z.B. eine ID o.ä. Das Bild selbst bitte nicht übergeben! Auf den Wert kanns du in der Paint Methode zugreifen es ist die Variable data.



```
public void paintBild(OutputStream out, Object data) throws IOException {
        //ID aus data lesen
        Long id = (Long) data;
       //Lazy Load zugriff auf meine DB
       byte[] pic =  sessionBean.find(id).getPic();
       //Bild malen
      out.write(pic);
    }
```


----------



## janpaet (6. Nov 2009)

Super Deadalus,
genau das wollte ich mal versuchen.

Leider habe ich da noch meine Verständnisschwierigkeiten:

- Was ist sessionBean?

Vielen Dank und Grüße
Jan


----------



## Deadalus (9. Nov 2009)

Hallo.

sessionBean ist einfach ein Objekt, (In dem Fall ein SessionBean) bei dem ich in der find() Methode die ID angebe um Daten aus der DB zu lesen. In dem Falle ein Objekt mit einem byte[] Bild als Attribut. 

In dieser Zeile musst du halt irgendwie an das gewünschte byte[] image kommen. Das so


----------

