# Umgang mit hochgeladenen Dateien



## Shaun0 (4. Jan 2013)

Hallo Zusammen,

wie geht ihr Allgemein mit von Usern hochgeladenen Dateien um? Z.B. Bildern.
Bei einem ablegen im .war würden diese ja eine Aktualisierung der Applikation nicht überleben.
Eine extra Datenbank finde ich jetzt auch nicht unbedingt Best Practice.
Was meint Ihr?

Grüße Shaun


----------



## Sym (4. Jan 2013)

Wieso eine extra DB? Du hast doch sicherlich schon eine, in der Applikation, oder? Falls nicht, nutze eine Embedded-DB.


----------



## Shaun0 (4. Jan 2013)

Macht es nicht mehr Sinn die Daten irgendwo statisch abzulegen und nur die Referenz in der Datenbank zu speichern?

Mein Erster Gedanke war folgender.


Bild wird von einem Benutzer hochgeladen
Bild wird in ei Größen konvertiert (klein, mittel, groß)
Bilder werden unter /images/ abgespeichert
Adressen der Bilder werden in einer Datenbank gespeichert

Die Java-Klasse zum speichern könnte so aussehen.

```
@Entity
public class UploadedImage {
@Id
Long id;
String title;
String description;
String path;
String middlePath;
String thumbPath;
}
```

Jedoch speichere ich ja jetzt die Bilder im .war-file.
Wenn ich nun ein Update der Anwendung machen würde, wären alle Bilder weg.


----------



## Templarthelast (4. Jan 2013)

Wie wäre es, wenn du die Bilder irgendwo auf einem Server speicherst? Alternativ kannst du auch den Inhalt des Bildes in einer Datenbank speichern.


----------



## Sym (4. Jan 2013)

Warum meinst Du, dass das Speichern auf der Platte besser sei als in einer DB? Was bringt Dir das für Vorteile? Die DB schreibt auch nur auf die Platte.


----------



## Shaun0 (4. Jan 2013)

@Templarthelast Genau, und wie kann ich dann den Ordner über http verfügbar machen? Ich nutzen den JBoss 7 als AS.

@Sym Die Bilder wären ja dann als BLOB gespeichert, ich müsste dann immer jedes Bild aus der DB laden. Wenn die Bilder aber über eine URI verfügbar wären, kann ich einfach ein JSF-Tag mit der Bild URI ausgeben. Die URI wäre dann in der DB gespeichert.


----------



## Templarthelast (4. Jan 2013)

Du willst den Ordner nicht direkt über http verfügbar machen, sondern die Datei über REST bzw. ein Servlet bereitstellen. Falls dann der entsprechende Pfad über http geladen wird, wird das Bild in den Output geschoben.


----------



## Shaun0 (4. Jan 2013)

Nicht ganz glaube ich.
Ich möchte die Bilder so speichern, dass im html am Ende einfach nur example.com/extern/images/image001.jpg oder so steht. Also schon REST-Like, da ich natürlich von außen auch die URI direkt aufrufen könnte um einfach nur das Bild anzuzeigen. Der Ordner darf nur nicht im .war liegen, da ja sonst nach jedem deploy alle Bilder weg wären.
Ich kann mich manchmal nicht ganz verständlich für andere Ausdrücken, danke für eure Mühe.


----------



## TheDarkRose (4. Jan 2013)

Templarthelast hat gesagt.:


> Du willst den Ordner nicht direkt über http verfügbar machen, sondern die Datei über REST bzw. ein Servlet bereitstellen. Falls dann der entsprechende Pfad über http geladen wird, wird das Bild in den Output geschoben.



Nein das will man bei einen statischen Content nicht. Solche Uploads macht man z.B. mit einem Apache in einer Subdomain oder einen Alias verfügbar.,

@Shaun
Weiß jetzt nicht wie es sich bei JBoss verhält, aber bei Tomcat und Spring schreibe ich Uploads immer in einen spezifischen Ordner außerhalb z.B. /var/www/myapp/uploads


----------



## TheDarkRose (4. Jan 2013)

---doppelpost---


----------



## deetee (4. Jan 2013)

TheDarkRose hat gesagt.:


> Nein das will man bei einen statischen Content nicht. Solche Uploads macht man z.B. mit einem Apache in einer Subdomain oder einen Alias verfügbar.,
> 
> @Shaun
> Weiß jetzt nicht wie es sich bei JBoss verhält, aber bei Tomcat und Spring schreibe ich Uploads immer in einen spezifischen Ordner außerhalb z.B. /var/www/myapp/uploads



Du meinst den Apache HTTP Webserver? Auf welche Ports sind bei dir dann die Server konfiguriert?


----------



## TheDarkRose (4. Jan 2013)

Tomcat oder ein AS horcht immer nur lokal. Apache spielt dann Proxy, damit das Java EE Zeugsl auf Port 80 erreichbar ist. Und stellt zusätzlich noch statischen Content zur Verfügung.

Nie im Leben würde ich einen JBoss auf Port 80 lauschen lassen. Entweder muss man ihn als root starten oder es ist ein herumgefrickel, das ein nicht-root User auf Ports <1024 lauschen darf.


----------



## ARadauer (4. Jan 2013)

Der Vorteil von bildern in der datenbank ist natürlich, dass du cluster fähig bleibst...

Und auch wenn das bild als Blob in der Db ist kann man es einfach im <img tag angeben, man gibt einfach die url eines servlets an die das bild aus der db lädt und zurück streamt... ein 10 zeiler...


----------



## deetee (4. Jan 2013)

Ich kenne da noch die Variante einen Host Context, z.B. 


```
<Context docBase="/path/of/images" path="/images" />
```

Damit sind die Bilder unter mydomain.de erreichbar und müssen beim Hochladen eben nach /path/of/images kopiert werden.

Damit kann man sich den Apache sparen. Würde ich aber auch nur für kleine bis mittlere Projekte so machen.


----------



## TheDarkRose (4. Jan 2013)

ARadauer hat gesagt.:


> Der Vorteil von bildern in der datenbank ist natürlich, dass du cluster fähig bleibst...
> Und auch wenn das bild als Blob in der Db ist kann man es einfach im <img tag angeben, man gibt einfach die url eines servlets an die das bild aus der db lädt und zurück streamt... ein 10 zeiler...



Kann man, aber es sind nach dem Upload statische Contents. Warum dynamisch arbeiten, wenn man es dann statisch ausliefern und Caching und und und...
Clusterfähig bleibt man auch, denke da an GlusterFS und was es noch alles gibt für Dateisysteme.




deetee hat gesagt.:


> Ich kenne da noch die Variante einen Host Context, z.B.
> [...]
> Damit kann man sich den Apache sparen. Würde ich aber auch nur für kleine bis mittlere Projekte so machen.


Ja, kann schon sein, aber ist sicher auch von AS zu AS unterschiedlich..
Aber IMHO empfiehlt jeder der EE Apps vertreibt, einen Apache oder anderen HTTP-Server als Proxy vorzuschalten. Alleine schon, weil es ohne Rootrechte nicht einfach möglich ist den EE-Server auf Port 80 zu binden.

Ergo Proxy kann/sollte man bei jedem Projekt so machen.

VHost-Beispiel für Apache:


```
<VirtualHost *:80>
	ServerAdmin webmaster@example.com
	ServerName jira.example.com

	# JIRA Proxy Configuration:
	<Proxy *>
	        Order deny,allow
	        Allow from all
	</Proxy>

	ProxyRequests           Off
	ProxyPreserveHost       On
	ProxyPass / http://localhost:8080/
	ProxyPassReverse / http://localhost:8080/

	ErrorLog /var/log/apache2/jira-eval-error.log
	LogLevel warn

	CustomLog /var/log/apache2/jira-eval-access.log combined
	ServerSignature Off
</VirtualHost>
```


----------



## deetee (4. Jan 2013)

Stimmt schon, die meisten Sysadmins konfigurieren immer einen Apache Webserver als Proxy. Es ist aber nicht zwingend, darauf wollte ich nur hinweisen.


----------



## TheDarkRose (4. Jan 2013)

Im Development nicht, aber im Produktivsystemen IMHO Pflicht.


----------



## Ullenboom (5. Jan 2013)

Unabhängig von der Diskussion, ob Bilder besser in einer DB oder im DS abgelegt werden, ist es unerlässlich, sich dagegen abzusichern, dass Benutzer "unendlich" große "Bilder" hochladen. Entweder macht das die Uploader-Lib, oder wenn man das selbst programmiert, sollte man sich z.B. ByteStreams (Guava: Google Core Libraries for Java 14.0-rc1 API), long) anschauen.


----------



## Shaun0 (5. Jan 2013)

Jetzt hat das ganze doch schon ein bisschen Fahrt bekommen.



Ullenboom hat gesagt.:


> Unabhängig von der Diskussion, ob Bilder besser in einer DB oder im DS abgelegt werden, ist es unerlässlich, sich dagegen abzusichern, dass Benutzer "unendlich" große "Bilder" hochladen. Entweder macht das die Uploader-Lib, oder wenn man das selbst programmiert, sollte man sich z.B. ByteStreams (Guava: Google Core Libraries for Java 14.0-rc1 API), long) anschauen.


Danke für den Hinweis, wird über einen Parameter gesteuert.



deetee hat gesagt.:


> Ich kenne da noch die Variante einen Host Context, z.B.
> ...
> Damit sind die Bilder unter mydomain.de erreichbar und müssen beim Hochladen eben nach /path/of/images kopiert werden.
> 
> Damit kann man sich den Apache sparen. Würde ich aber auch nur für kleine bis mittlere Projekte so machen.


Ich glaube der Weg mit einem Host Context geht beim JBoss 7 nicht mehr. https://issues.jboss.org/browse/AS7-3357



TheDarkRose hat gesagt.:


> Tomcat oder ein AS horcht immer nur lokal. Apache spielt dann Proxy, damit das Java EE Zeugsl auf Port 80 erreichbar ist. Und stellt zusätzlich noch statischen Content zur Verfügung.
> 
> Nie im Leben würde ich einen JBoss auf Port 80 lauschen lassen. Entweder muss man ihn als root starten oder es ist ein herumgefrickel, das ein nicht-root User auf Ports <1024 lauschen darf.


 Einen Apache davor zu setzen scheint mir plausibel und geht in die Richtung statischen Content ohne großen Ressourcenverbrauch auszuliefern. Danke. Ich habe schon einiges mehr an Stoff zum lesen zu diesem Thema gefunden.


Wenn man keinen Apache einsetzen will und AS unabhängig bleiben will, gibt es eine Lösung von BalusC. The BalusC Code: FileServlet supporting resume and caching and GZIP


----------

