[JAVA] Comment télécharger des fichiers (Servlet, HTML, Apache, Tomcat)

Nous avons résumé les paramètres de téléchargement de fichiers sur un système Web en liant Tomcat et Apache. [Environnement confirmé]

Environnement au moment de la confirmation

Télécharger avec Servlet

Définissez le type de contenu sur ʻapplication / octat-stream`

response.setContentType("application/octet-stream");
response.getWriter().write("Hello World");

https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/MIME_types

Il s'agit de la valeur par défaut pour les fichiers au format binaire. Il représente en fait un fichier au format binaire inconnu, et le navigateur ne l'exécute généralement pas automatiquement ou ne demande pas s'il doit s'exécuter. Ils traitent la valeur de l'en-tête Content-Disposition comme s'il s'agissait d'une pièce jointe et suggèrent de l'enregistrer en tant que fichier.

Définissez la valeur de l'en-tête Content-Disposition sur ʻattachment`

Comme mentionné ci-dessus, vous pouvez le télécharger en spécifiant ʻapplication / octat-stream comme type de contenu. Cependant, si vous connaissez le type de fichier à télécharger, il est étrange de spécifier ʻapplication / octat-stream.

Comme indiqué ci-dessous, si vous spécifiez ʻattachment` dans l'en-tête Content-Disposition, vous pouvez télécharger même si le type de contenu n'est pas "application / octat-stream".

response.setContentType("text/html");
response.setHeader("Content-Disposition","attachment");
response.getWriter().write("Hello World");

Nom de fichier par défaut au moment du téléchargement

La valeur spécifiée pour filename sera le nom de fichier par défaut au moment du téléchargement.

response.setHeader("Content-Disposition","attachment;filename=\"sample.html\"");
// attachment;filename="sample.html"

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

When used in combination with Content-Disposition: attachment, it is used as the default filename for an eventual 'Save As" dialog presented to the user.

Si le nom de fichier contient des caractères codés sur deux octets, utilisez filename *.

String encodedFilename = URLEncoder.encode("échantillon.html", "UTF-8");
response.setHeader("Content-Disposition","attachment;filename*=\"UTF-8''" + encodedFilename + "\"");

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

The parameters "filename" and "filename*" differ only in that "filename*" uses the encoding defined in RFC 5987. When both "filename" and "filename*" are present in a single header field value, "filename*" is preferred over "filename" when both are present and understood.

Veuillez noter que les caractères blancs demi-largeur sont convertis en signe plus "+". Le code ci-dessous aura le nom de fichier ʻa + b.html`.

String encodedFilename = URLEncoder.encode("a b.html", "UTF-8");
response.setHeader("Content-Disposition","attachment;filename*=\"UTF-8''" + encodedFilename + "\"");

Il s'agit d'une spécification Java URL Encoder. https://docs.oracle.com/javase/jp/8/docs/api/java/net/URLEncoder.html

Le caractère vide "" est converti en signe plus "+".

Si vous remplacez «+» par «% 20», un caractère vide sera affiché dans le nom du fichier. Au fait, URLEncode a des dialectes en fonction de la langue, donc je ne vais pas y entrer. .. .. https://www.glamenv-septzen.net/view/1170

Les caractères qui ne peuvent pas être utilisés dans le nom de fichier sont convertis en traits de soulignement. Le code ci-dessous aura le nom de fichier «_________. Html».

// ¥ / : * ? " < > |Nom de fichier comprenant
String encodedFilename = URLEncoder.encode("\\/:*\"<>|.html", "UTF-8");
response.setHeader("Content-Disposition","attachment;filename*=\"UTF-8''" + encodedFilename + "\"");

«Filename» et «filename *»

Si vous écrivez à la fois filename et filename * ʻ comme indiqué ci-dessous, filenamesera ignoré sifilename *est valide. Si vous considérez un navigateur qui ne prend pas en chargefilename *` (existe-t-il un tel navigateur en 2017?), Il semble bon de l'écrire ensemble.

String encodedFilename = URLEncoder.encode("échantillon.html", "UTF-8");
response.setHeader("Content-Disposition","attachment;" + 
  "filename=\"sample.html\"" + 
  "filename*=\"UTF-8''" + encodedFilename + "\"");

Therefore, when both "filename" and "filename*" are present in a single header field value, recipients SHOULD pick "filename*" and ignore "filename".

Guillemets doubles pour filaname *

Dans l'exemple RFC 6266, «filename» a un guillemet double, mais «filename *» n'en a pas.

Content-Disposition: attachment;
                     filename="EURO rates";
                     filename*=utf-8''%e2%82%ac%20rates

Lorsque filename * est entre guillemets (filename * =" utf-8''sample.html "), le résultat du téléchargement de chaque navigateur est le suivant.

A part Firefox, filename * était ignoré et le nom de fichier était "download".

Télécharger des fichiers sous Apache

Activez mod_headers et spécifiez l'en-tête Content-disposition. Le code suivant téléchargera tous les fichiers xml sous Apache.

LoadModule headers_module modules/mod_headers.so

<FilesMatch "\.(xml)$">
    Header set Content-Disposition attachment
</FilesMatch>

[Site de référence] http://qiita.com/kompiro/items/ac60721bc43625a057dc

Si vous accédez à http: // sample.co.jp / sample.xml, il sera téléchargé avec le nom de fichier" sample.xml ". Notez que le nom du fichier est inclus dans l'URL. Si le nom de fichier contient des caractères qui ont une signification particulière comme URL, il ne sera pas téléchargé correctement. Les noms de fichiers contenant les caractères suivants n'ont pas été téléchargés correctement. (Vérifiez avec Firefox. On ne sait pas si ce sont tous les caractères qui ne peuvent pas être utilisés dans le nom de fichier)

 # %

Télécharger en HTML un élément

Si l'attribut de téléchargement est spécifié dans l'élément a, la valeur spécifiée dans l'attribut de téléchargement sera téléchargée en tant que nom de fichier. Vous pouvez également utiliser des caractères pleine largeur, des espaces demi-largeur et «#», qui a une signification particulière en tant qu'URL. Cependant, IE n'est pas pris en charge ...

<a href="sample.png " download="Test a b#%.png ">Download</a>

https://developer.mozilla.org/ja/docs/Web/HTML/Element/a

Cet attribut indique au navigateur de télécharger au lieu de naviguer vers l'URL, invitant l'utilisateur à l'enregistrer en tant que fichier local. Si vous spécifiez une valeur pour l'attribut, elle sera interprétée comme le nom de fichier par défaut pour l'invite d'enregistrement (les utilisateurs peuvent le renommer si nécessaire). Il n'y a pas de limite aux valeurs qui peuvent être utilisées, mais / et \ sont convertis en traits de soulignement. De nombreux systèmes de fichiers ont des restrictions sur les caractères qui peuvent être utilisés dans les noms de fichiers, et le navigateur peut ajuster les noms de fichiers.

<a href="sample.png " download="Test a b#%.png ">Download</a>

Si vous spécifiez `\ /: *?" <> | ʻDans l'attribut de téléchargement, tous sont convertis en traits de soulignement (vérifiez avec Firefox). Le code ci-dessous aura le nom de fichier «_________. Html».

<a href="sample.png " download="&#x5c;/:*?&quot;&lt;&gt;|.png ">Download</a>

Précautions lors du téléchargement de fichiers sous Tomcat

Avant Tomcat 7 (?), La valeur par défaut pour ʻURIEncoding est ʻISO-8859-1. Ce code de caractère est un jeu de caractères de l'alphabet latin et ne peut pas représenter le japonais.

https://tomcat.apache.org/tomcat-7.0-doc/config/http.html#Common_Attributes

This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.

Par conséquent, si vous souhaitez télécharger un fichier contenant du japonais, vous devez définir le code de caractère sur UTF-8.

server.xml


<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           URIEncoding="UTF-8" /><!--← Addendum-->

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"
URIEncoding="UTF-8"  /><!--← Addendum-->

Dans Tomcat8, la valeur par défaut est UTF-8, vous n'avez donc pas besoin de le spécifier.

https://tomcat.apache.org/tomcat-8.0-doc/config/http.html#Common_Attributes

This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, UTF-8 will be used unless the org.apache.catalina.STRICT_SERVLET_COMPLIANCE system property is set to true in which case ISO-8859-1 will be used.

[Site de référence] http://qiita.com/kazuki43zoo/items/a365d194f5c4df28912f

Recommended Posts

Comment télécharger des fichiers (Servlet, HTML, Apache, Tomcat)
Comment télécharger une ancienne version d'Apache Tomcat
Créer un servlet Java et un fichier WAR JSP à déployer sur Apache Tomcat 9 avec Gradle
Comment réaliser le téléchargement de fichiers avec Feign
Comment passer d'Eclipse Java à un fichier SQL
Comment convertir un fichier en tableau d'octets en Java
Comment laisser un commentaire
Comment utiliser Apache POI
Comment insérer une vidéo
Comment créer une méthode
Comment demander un fichier CSV au format JSON avec jMeter
[Ruby] Comment diviser chaque requête GraphQL en fichiers
Comment déployer une application Java Servlet simple sur Heroku
Comment s'inscrire en tant que client dans Square à l'aide de Tomcat
Comment utiliser scope (JSP & Servlet)
Comment créer un fichier jar et un fichier war à l'aide de la commande jar
Transfert du fichier de guerre SCP vers Tomcat
Comment créer un fichier jar sans dépendances dans Maven
Comment créer un conteneur Java
Comment signer Minecraft MOD
Comment créer un pilote JDBC
Comment convertir un fichier erb en haml
Comment charger un fichier de téléchargement Spring et afficher son contenu
Comment lire un fichier et le traiter comme une entrée standard
[Swift] Comment envoyer une notification
Comment créer un écran de démarrage
Comment créer un plug-in Jenkins
Comment faire un projet Maven
[Débutant] Comment supprimer AUCUN FICHIER
Comment ouvrir un fichier de script à partir d'Ubuntu avec du code VS
[chown] Comment changer le propriétaire d'un fichier ou d'un répertoire
Comment créer un tableau Java
Comment passer du HTML à Haml
[IntelliJ IDEA] Comment ajouter automatiquement la finale lors de l'enregistrement d'un fichier Java
Comment exécuter un fichier GIF à partir de la ligne de commande Linux (Ubuntu)
Comment savoir quelle version Java d'un fichier de classe a été compilée
Comment démarrer un conteneur Docker avec un volume monté dans un fichier de commandes
Comment exécuter un contrat avec web3j
Comment trier une liste à l'aide du comparateur
Comment créer un résumé de calendrier Java
Un mémorandum sur l'utilisation d'Eclipse
[Java] Comment utiliser la classe File
[Basique] Comment écrire un auto-apprentissage Dockerfile ②
Comment insérer une vidéo dans Rails
Comment ajouter un nouveau hachage / tableau
Comment ajouter un fichier jar dans ScalaIDE
[Introduction à Java] Comment écrire un programme Java
Comment créer un robot Discord (Java)
Java: Comment envoyer des valeurs du servlet au servlet
[Servlet / Ajax] Comment résoudre NoClassDefFoundError [Eclipse]
[Swift5] Comment créer un écran de démarrage
[rails] Comment créer un modèle partiel
[Introduction à JSP + Servlet] Une petite animation ♬