2010-03-11 6 views
7

Je développe un téléchargement de fichier avec JSF. L'application enregistre trois dates sur le fichier:Quand les navigateurs envoient-ils l'application/octet-stream en tant que Content-Type?

  • Nom du fichier
  • Octets
  • Content-Type présenté par le navigateur.

Mon problème est que certains fichiers sont enregistrés avec le type de contenu = application/octet-stream même si elles sont *.doc fichiers oder *.pdf.

Quand le navigateur soumet-il un tel type de contenu?
Je voudrais nettoyer la base de données ainsi j'ai besoin de savoir quand les informations de navigateur sont incorrectes.

+1

Hmm ... Je ne peux pas faire en sorte que Firefox utilise un mauvais type MIME même si je gâche le fichier mime.types de mon système, donc je ne sais pas ce que les navigateurs pourraient faire pour passer un en-tête Content-type. – Pointy

+0

@Pointy: Malheureusement, il y a plus de navigateurs dans le monde que seulement FF. Par exemple celui développé par (toux) une équipe à Redmond. – BalusC

+0

Oui bien sûr - curieusement, je m'attendrais à ce que IE obtienne le type MIME, mais pas de cette façon. (Je m'attendrais à ce qu'il fournisse "application/pdf" pour un fichier JPEG dont le nom est "bogus.pdf", par exemple.) – Pointy

Répondre

8

Ignore la valeur envoyée par le navigateur. Cela dépend en effet de la plateforme client, du navigateur et de la configuration utilisée.

Si vous souhaitez un contrôle total sur les types de contenu en fonction de l'extension du fichier, mieux vaut le déterminer vous-même en utilisant ServletContext#getMimeType().

String mimeType = servletContext.getMimeType(filename); 

Par défaut, les types MIME sont DÉFINIES dans le web.xml du servletcontainer en question. Dans Tomcat par exemple, il est situé au /conf/web.xml. Vous pouvez étendre/remplacer dans /WEB-INF/web.xml de la webapp comme suit:

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

Vous pouvez également déterminer le type MIME en fonction du contenu réel du fichier (car l'extension de fichier ne peut pas en soi être précis, il peut se laisser berner par le client), mais c'est beaucoup de travail. Pensez à utiliser une bibliothèque tierce pour faire tout le travail. J'ai trouvé JMimeMagic utile pour cela. Vous pouvez l'utiliser comme suit:

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

Notez qu'il ne supporte pas tous mimetypes comme fiable. Vous pouvez également envisager une combinaison des deux approches. Par exemple. si l'un renvoie null ou application/octet-stream, utilisez l'autre. Ou si les deux retournent un type MIME différent mais "valide", préférez celui retourné par JMimeMagic.

Oh, j'ai presque oublié d'ajouter, dans JSF, vous pouvez obtenir le ServletContext comme suit:

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

Ou si vous arrive d'utiliser JSF 2.x déjà, utilisez ExternalContext#getMimeType() à la place.

2

Cela dépend du système d'exploitation, du navigateur et de la façon dont l'utilisateur les a configurés. C'est basé sur la façon dont le navigateur détermine le type de fichiers locaux (pour les afficher). Sur la plupart des combinaisons OS/navigateur, cela est basé sur l'extension du fichier, mais sur certains, il peut être déterminé par d'autres moyens. (par exemple: sur Mac OS)

Dans ce cas, vous ne devriez pas vraiment compter sur le type de contenu envoyé par le navigateur. La meilleure approche serait de regarder réellement le contenu du fichier. Vous pouvez probablement aussi utiliser le nom de fichier, mais gardez à l'esprit que les navigateurs ne seront pas forcément bons à vous le dire (bien que ce soit probablement un plus fiable que le type de contenu qu'ils envoient).