2010-03-11 3 views
7

Ich entwickle einen Datei-Upload mit JSF. Die Anwendung speichert drei Daten über die Datei:Wann senden Browser application/octet-stream als Content-Type?

  • Dateiname
  • Bytes
  • Content-Type, wie durch den Browser übermittelt.

Mein Problem ist, dass einige Dateien mit Inhaltstyp gespeichert werden = application/octet-stream auch wenn sie *.doc Dateien oder *.pdf.

Wann sendet der Browser einen solchen Inhaltstyp?
Ich möchte die Datenbank aufräumen, also muss ich wissen, wenn die Browserinformationen falsch sind.

+1

Hmm ... Ich kann Firefox nicht verwenden einen schlechten MIME-Typ, auch wenn ich meine System mime.types-Datei durcheinander bringen, so bin ich mir nicht sicher, was die Browser tun, um eine Content-Type-Header zu übergeben. – Pointy

+0

@Pointy: Leider gibt es auf der Welt mehr Browser als nur FF. Zum Beispiel das von (hust) entwickelte Team in Redmond. – BalusC

+0

Ja natürlich - merkwürdigerweise würde ich erwarten, dass IE den MIME-Typ falsch bekommt, aber nicht auf diese Weise. (Ich würde erwarten, dass es "application/pdf" für eine JPEG-Datei liefert, deren Name zufällig "bogus.pdf" ist.) – Pointy

Antwort

8

Ignoriere den vom Browser gesendeten Wert. Dies ist in der Tat abhängig von der verwendeten Client-Plattform, Browser und Konfiguration.

Wenn Sie die vollständige Kontrolle über Inhaltstypen basierend auf der Dateierweiterung haben möchten, dann bestimmen Sie sie besser selbst mit ServletContext#getMimeType().

String mimeType = servletContext.getMimeType(filename); 

Die Standard-Mime-Typen sind in den web.xml des servletcontainer in Frage definiertem. In zum Beispiel Tomcat, ist es in /conf/web.xml. Sie können es in der Webapp des ausfahren/außer Kraft setzen /WEB-INF/web.xml wie folgt:

<mime-mapping> 
    <extension>xlsx</extension> 
    <mime-type>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</mime-type> 
</mime-mapping> 

Sie können auch den MIME-Typ bestimmen auf dem tatsächlichen Dateiinhalt basiert (weil die Dateierweiterung kann nicht per se genau sein, kann es durch täuschen der Kunde), aber das ist eine Menge Arbeit. Erwägen Sie die Verwendung einer 3rd-Party-Bibliothek, um die ganze Arbeit zu erledigen. Ich habe JMimeMagic nützlich gefunden. Sie können es wie folgt:

String mimeType = Magic.getMagicMatch(file, false).getMimeType(); 

Beachten Sie, dass es nicht alle MIME-Typen als zuverlässig unterstützt. Sie können auch eine Kombination beider Ansätze in Betracht ziehen. Z.B. Wenn die eine Null oder application/octet-stream zurückgibt, verwenden Sie die andere. Oder wenn beide einen anderen, aber "gültigen" MIME-Typ zurückgeben, bevorzugen Sie den von JMimeMagic zurückgegebenen.

Oh, hätte ich fast vergessen hinzuzufügen, in JSF können Sie die ServletContext erhalten wie folgt:

ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext(); 

Oder wenn Sie JSF 2.x geschehen bereits verwenden möchten, verwenden ExternalContext#getMimeType() statt.

2

Dies hängt vom Betriebssystem, vom Browser und davon ab, wie der Benutzer sie konfiguriert hat. Es basiert auf der Art und Weise, wie der Browser den Dateityp der lokalen Dateien bestimmt (um sie anzuzeigen). Bei den meisten Betriebssystem-/Browser-Kombinationen basiert dies auf der Erweiterung der Datei, bei einigen kann sie jedoch auf andere Weise bestimmt werden. (zB: unter Mac OS)

In jedem Fall sollten Sie sich nicht wirklich auf den vom Browser gesendeten Inhaltstyp verlassen. Der beste Weg wäre, den Inhalt der Datei zu betrachten. Sie könnten wahrscheinlich auch den Dateinamen verwenden, aber denken Sie daran, dass Browser nicht unbedingt gut darin sind, Ihnen das zu sagen (obwohl es wahrscheinlich immer noch eine zuverlässigere Version ist als der Inhaltstyp, den sie senden).