Les en-têtes HTTP de codage/décodage en Java
Un en-tête HTTP personnalisé est passé à une Servlet application à des fins d'authentification. La valeur d'en-tête doit être en mesure de contenir les accents et autres caractères non-ASCII, ce doit être dans un certain encodage (idéalement UTF-8).
Je suis fournies avec ce morceau de code Java par les développeurs qui contrôle l'authentification de l'environnement:
String firstName = request.getHeader("my-custom-header");
String decodedFirstName = new String(firstName.getBytes(),"UTF-8");
Mais ce code n'est pas bon pour moi: elle suppose le codage de la valeur d'en-tête, quand il me semblait qu'il y avait une bonne façon de spécifier un encodage pour les valeurs d'en-tête (du MIME, je crois).
Voici ma question: quelle est la bonne façon (tm) de traiter avec en-tête personnalisé valeurs qui ont besoin de l'appui d'un encodage UTF-8:
- sur le fil (la façon dont la tête ressemble sur le fil)
- du décodage point de vue (comment le décoder à l'aide de Java Servlet API, et peut-on supposer que la demande.getHeader() déjà bien fait le décodage)
Ici est un environnement indépendant de l'exemple de code pour traiter les en-têtes comme de l'UTF-8 dans le cas où vous ne pouvez pas changer votre service:
String valueAsISO = request.getHeader("my-custom-header");
String valueAsUTF8 = new String(firstName.getBytes("ISO8859-1"),"UTF-8");
OriginalL'auteur ebruchez | 2008-11-27
Vous devez vous connecter pour publier un commentaire.
De nouveau: la RFC 2047 n'est pas mis en œuvre dans la pratique. La prochaine révision de HTTP/1.1 va supprimer toute mention de celui-ci.
Donc, si vous avez besoin de transport des caractères non-ASCII, le moyen le plus sûr est de coder en une séquence de caractères ASCII, tels que le "Slug" tête dans le Protocole de Publication Atom.
Atome slug en-tête semble effectivement utiliser RFC2047:
Clients MAY send non-ASCII characters in the Slug entity-header, which they MUST encode using "encoded-words", as defined in [RFC2047].
, selon bitworking.org/projects/atom/...Eugene: c'est un début de projet de l'Atome. C'est différent dans la publication de la RFC (RFC 4287)
OriginalL'auteur
La HTTPbis groupe de travail est conscient du problème, et les dernières traites de se débarrasser de toutes les langues par rapport au TEXTE et à la RFC 2047 encodage -- il n'est pas utilisé dans la pratique sur HTTP.
Voir http://trac.tools.ietf.org/wg/httpbis/trac/ticket/74 pour l'ensemble de l'histoire.
Il est éliminé dans les brouillons.
Quand est la prochaine révision de HTTP 1.1" va être?
Pacerier: lists.w3.org/Archives/Public/ietf-http-wg/2011OctDec/0511.html
Ic, on dirait que nous n'avons pas à attendre de l'anthère de 10 ans lol
OriginalL'auteur Julian Reschke
Voir le HTTP spec pour les règles, ce qui est dit dans la section 2.2
Le code ci-dessus ne sera pas décoder correctement un RFC2047 l'encodage de la chaîne, m'amenant à croire que le service ne fonctionne pas correctement, suivez les spec, et ils ont juste embeding premières données utf-8 dans l'en-tête.
OriginalL'auteur superfell
Comme déjà mentionné, le premier regard doit toujours aller à la HTTP 1.1 spec (RFC 2616). Il dit ce texte dans les en-têtes doivent utiliser le codage MIME, tel que défini RFC 2047 si elle contient des caractères à partir de jeux de caractères autres que l'ISO-8859-1.
Voici donc un plus pour vous. Si vos besoins sont couverts par la norme ISO-8859-1 jeu de caractères puis il vous suffit de mettre vos personnages dans vos messages de requête/réponse. Sinon codage MIME est la seule alternative.
Aussi longtemps que l'utilisateur de l'agent envoie les valeurs de vos en-têtes personnalisés selon ces règles, vous n'aurez pas à vous soucier de les décoder. C'est ce que la Servlet API devrait le faire.
Cependant, il y a une raison fondamentale pour laquelle votre code sniplet ne fait pas ce qu'il est censé. La première ligne récupère la valeur d'en-tête en tant que Java chaîne. Comme nous le savons, il est représenté comme UTF8 en interne, de sorte à ce point, le HTTP message de demande d'analyse est déjà fait et terminé.
La ligne suivante récupère le tableau d'octets de cette chaîne. Depuis l'encodage n'a été spécifié (à mon humble avis, cette méthode sans argument doit avoir été déprécié, il y a longtemps), l'actuel système de codage par défaut est utilisé, ce qui n'est pas de l'utf-8, puis le tableau est à nouveau convertis comme étant encodés en utf-8. Outch.
Une petite correction: Java, les Chaînes ne sont PAS représentés en tant que UTF-8 en interne à tous. La représentation est proche de l'UCS-2 (qui est similaire à UTF-16). À toutes fins pratiques, l'encodage/décodage uniquement les questions lors de la conversion des Cordes de Java dans les représentations extérieures.
OriginalL'auteur mkoeller
Merci pour les réponses. Il semble que l'idéal serait de suivre le bon en-tête HTTP de codage selon la RFC 2047. Valeurs d'en-tête en UTF-8 sur le fil ressemblerait à quelque chose comme ceci:
Maintenant, voici la chose drôle: il semble que ni Tomcat 5.5 ou 6 correctement décode les en-têtes HTTP conformément à la RFC 2047! Le Tomcat code suppose partout que les valeurs d'en-tête d'utiliser ISO-8859-1.
Donc pour Tomcat, plus précisément, je vais contourner par écrit au moyen d'un filtre qui gère le bon décodage de l'en-tête de valeurs.
OriginalL'auteur ebruchez