web-dev-qa-db-fra.com

HTML: le formulaire n'envoie pas d'entrées au format UTF-8

J'ai visité chacune des questions sur le codage UTF-8 en HTML et rien ne semble le faire fonctionner correctement.

J'ai ajouté la balise meta: rien n'a changé.
J'ai ajouté l'attribut accept-charset dans form: rien n'a changé.


Fichier JSP

<%@ page pageEncoding="UTF-8" %>
<%@ taglib uri="http://Java.Sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Editer les sous-titres</title>
</head>
<body>
    <form method="post" action="/Subtitlor/edit" accept-charset="UTF-8"> 
        <h3 name="nameOfFile"><c:out value="${ nameOfFile }"/></h3> 
        <input type="hidden" name="nameOfFile" id="nameOfFile" value="${ nameOfFile }"/>
        <c:if test="${ !saved }">
            <input value ="Enregistrer le travail" type="submit" style="position:fixed; top: 10px; right: 10px;" />
        </c:if>
        <a href="/Subtitlor/" style="position:fixed; top: 50px; right: 10px;">Retour à la page d'accueil</a>
        <c:if test="${ saved }">
            <div style="position:fixed; top: 90px; right: 10px;">
                <c:out value="Travail enregistré dans la base de donnée"/>
            </div>
        </c:if>
        <table border="1">
            <c:if test="${ !saved }">
                <thead>
                    <th style="weight:bold">Original Line</th>
                    <th style="weight:bold">Translation</th>
                    <th style="weight:bold">Already translated</th>
                </thead>
            </c:if>
            <c:forEach items="${ subtitles }" var="line" varStatus="status">
                <tr>
                    <td style="text-align:right;"><c:out value="${ line }" /></td>
                    <td><input type="text" name="line${ status.index }" id="line${ status.index }" size="35" /></td>
                    <td style="text-align:right"><c:out value="${ lines[status.index].content }"/></td>
                </tr>
            </c:forEach>
        </table>
    </form>
</body>
</html>

Servlet

for (int i = 0 ; i < 2; i++){
    System.out.println(request.getParameter("line"+i));
}

Sortie

Et ton père et sa soeur
Il ne sera jamais parti.
7
Yassin Hajaj

J'ai ajouté la balise meta: rien n'a changé.

Cela n'a en effet aucun effet lorsque la page est servie sur HTTP au lieu de, par exemple. depuis le système de fichiers du disque local (c’est-à-dire que l’URL de la page est http://... au lieu de par exemple file://...). En HTTP, le jeu de caractères dans l'en-tête de réponse HTTP sera utilisé. Vous l'avez déjà défini comme ci-dessous:

<%@page pageEncoding="UTF-8"%>

Cela non seulement écrira la réponse HTTP en utilisant UTF-8, mais définira également l'attribut charset dans l'en-tête de réponse Content-Type.

Celui-ci sera utilisé par le navigateur Web pour interpréter la réponse et encoder tous les paramètres de formulaire HTML.


J'ai ajouté l'attribut accept-charset dans form: rien n'a changé.

Cela n'a d'effet que dans le navigateur Microsoft Internet Explorer. Même alors, il le fait à tort. Ne l'utilisez jamais. Tous les navigateurs Web réels utiliseront à la place l'attribut charset spécifié dans l'en-tête Content-Type de la réponse. Même MSIE le fera de la bonne manière tant que vous spécifiez not l'attribut accept-charset. Comme indiqué précédemment, vous l'avez déjà correctement défini via pageEncoding.


Débarrassez-vous des balises meta et accept-charset. Ils n’ont pas d’effet utile et ne peuvent que vous embrouiller à long terme et même aggraver les choses lorsque l’utilisateur final utilise MSIE. Il suffit de s'en tenir à pageEncoding. Au lieu de répéter la pageEncoding sur toutes les pages JSP, vous pouvez également la définir globalement dans web.xml comme ci-dessous:

<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <page-encoding>UTF-8</page-encoding>
    </jsp-property-group>
</jsp-config>

Comme indiqué, cela indiquera au moteur JSP d'écrire la sortie de réponse HTTP à l'aide de UTF-8 et de la définir également dans l'en-tête de réponse HTTP. Le navigateur Web utilisera le même jeu de caractères pour coder les paramètres de la requête HTTP avant de le renvoyer au serveur. 

Votre seule étape manquante est d'indiquer au serveur qu'il doit utiliser UTF-8 pour décoder les paramètres de la requête HTTP avant de renvoyer des appels getParameterXxx(). Comment faire cela globalement dépend de la méthode de requête HTTP. Étant donné que vous utilisez la méthode POST, il est relativement facile d'y parvenir avec la classe de filtre de servlet ci-dessous, qui se raccorde automatiquement à toutes les demandes:

@WebFilter("/*")
public class CharacterEncodingFilter implements Filter {

    @Override
    public void init(FilterConfig config) throws ServletException {
        // NOOP.
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // NOOP.
    }
}

C'est tout. Dans Servlet 3.0+ (Tomcat 7 et versions ultérieures), vous n'avez pas besoin d'une configuration supplémentaire de web.xml.

N'oubliez pas qu'il est très important que la méthode setCharacterEncoding() soit appelée avant, les paramètres de demande POST sont obtenus pour la première fois à l'aide de l'une des méthodes getParameterXxx(). En effet, ils ne sont analysés qu'une seule fois lors du premier accès, puis mis en cache dans la mémoire du serveur.

Donc, par exemple séquence ci-dessous est faux:

String foo = request.getParameter("foo"); // Wrong encoding.
// ...
request.setCharacterEncoding("UTF-8"); // Attempt to set it.
String bar = request.getParameter("bar"); // STILL wrong encoding!

Effectuer le travail setCharacterEncoding() dans un filtre de servlet garantira qu'il est exécuté à temps (au moins avant tout servlet).


Si vous souhaitez que le serveur décode les paramètres de requête GET (et non POST) à l’aide de UTF-8 également (paramètres que vous voyez après le caractère ? dans l’URL, vous savez), vous devez le configurer dans le fin du serveur. Il n'est pas possible de le configurer via l'API servlet. Si vous utilisez par exemple Tomcat comme serveur, il suffit d'ajouter l'attribut URIEncoding="UTF-8" dans l'élément <Connector> du propre /conf/server.xml de Tomcat. 

Si vous voyez toujours Mojibake dans la sortie de la console des appels System.out.println(), il est fort probable que la sortie standard ne soit pas configurée pour utiliser UTF-8. Comment faire cela dépend de qui est responsable de l'interprétation et de la présentation de la sortie standard. Si vous utilisez par exemple Eclipse comme IDE, il suffit alors de définir Fenêtre> Préférences> Général> Espace de travail> Codage de fichier texte sur UTF-8.

Voir également:

24
BalusC

Sur la base de votre sortie publiée, il semble que le paramètre soit envoyé au format UTF8. Plus tard, les octets unicode de la chaîne sont interprétés au format ISO-8859-1.

L'extrait suivant montre votre comportement observé

String eGrave = "\u00E8"; // the letter è
System.out.printf("letter UTF8      : %s%n", eGrave);
byte[] bytes = eGrave.getBytes(StandardCharsets.UTF_8);
System.out.printf("UTF-8 hex        : %X %X%n",
        bytes[0], bytes[1], bytes[0], bytes[1]
);
System.out.printf("letter ISO-8859-1: %s%n",
        new String(bytes, StandardCharsets.ISO_8859_1)
);

sortie

letter UTF8      : è
UTF-8 hex        : C3 A8
letter ISO-8859-1: è

Pour moi, le formulaire envoie les données encodées UTF8 correctes, mais plus tard, ces données ne sont pas traitées comme UTF8.

edit Quelques autres points à essayer:

sortir le caractère encodant votre demande a

System.out.println(request.getCharacterEncoding())

force l'utilisation de UTF-8 pour récupérer le paramètre (non testé, seulement une idée)

request.setCharacterEncoding("UTF-8");
... request.getParameter(...);
2
SubOptimal

Vous pouvez utiliser des chaînes liées à ISO dans votre jeu de caractères et des définitions pageEncoding dans votre code JSP.

Comme charset = "ISO-8859-1" et pageEncoding = "ISO-8859-1".

0
IndTechVJ

Il y a un bug dans Tomcat qui peut vous piéger. Le premier filtre définit l'encodage sur lequel est basée la demande. 

Tous les autres filtres ou servlets situés derrière le premier filtre ne peuvent plus modifier le codage de la requête.

Je ne pense pas que ce bogue sera corrigé à l'avenir car les applications actuelles peuvent s'appuyer sur l'encodage.

0
Peter Rader