~/home of geeks

Download JSPs

· 309 Wörter · 2 Minute(n) Lesedauer

In vielen Beispielen wird darauf eingegangen, wie man mit einem Servlet Binary-Content Downloads streamen kann. Das ganze geht auch per JSP. Obwohl das ganze recht trivial ist, hier ein paar wichtige Details, die sehr hilfreich sind.

Um Binary Content durch ein Servlet oder JSP zu Streamen, sollte man neben den Binärdaten auch folgende Informationen über die Datei parat haben: Dateiname sowie Mime / Content Type.

Daher gehe ich von einem Objekt aus, welches in der folgenden Klasse gekapselt ist:

public interface BinaryObject {
  public String getName();
  public String getMimeType();
  public byte[] getContent();
}

Gefüllt werden kann ein solches Objekt durch die Dateiattribute eines File-Objektes, oder durch die Spalten einer Datenbank.

Ein Servlet würde das ganze in etwa wie folgt an einen Client streamen:

if (myBinaryObject.getContentType()==null ||
     myBinaryObject.getContentType().trim().length()<=0){
  response.setContentType("application/octet-stream");
}
else{
  response.setContentType(myBinaryObject.getContentType());
}
if (myBinaryObject.getName()==null ||
    myBinaryObject.getName().trim().length()<=0){
  response.setHeader("Content-Disposition",
    "filename=unknown");
}
else{
  response.setHeader("Content-Disposition",
    "filename="+myBinaryObject.getName());
}
OutputStream sout = response.getOutputStream();
byte [] data = myBinaryObject.getContent();
sout.write(data, 0, data.length);
sout.flush();

Man beachte, wie der Header des Response-Objektes mit “Content-Disposition” einen Dateinamen erhält.

In einer JSP sieht der Code fast genauso aus. Auf etwas ist jedoch zu achten. Bei JSP’s werden üblicherweise alle Zeichen außerhalb der Java-Blöcke als Text an den Client gestreamt. Dies kann dazu führen, dass Zeichen, wie Leerzeichen, Linefeeds etc. vor oder nach dem Binary Content an den Client gestreamt werden und damit Probleme bereiten. Auch werden Default-Contenttypes und Headerfelder durch die JSP API gesetzt, welche dann zu Fehlern führen. Um das alles zu vermeiden, muss lediglich die Methode reset() des ServletResponse-Objektes vor dem Streamen aufgerufen werden, welcher alle bis dahin vorgenommenen Einstellungen und Buffer zurücksetzt. Zusätzlich sollte man nach dem Streamen die JSP-Methode sofort mit return verlassen, damit sich auch am Ende keine Zeichen einschleichen.

response.reset();
// [... das Streamen]
return;

Ansonsten sind beide Varianten äquivalent. Die Servlet-Version ist sicherlich schlanker, dafür ist die JSP-Version einfacher zu warten und auszutauschen.