2010-06-12 4 views
29

J'ai un problème avec UTF-8. Mon client (réalisé en GWT) faire une demande à mon servlet, avec quelques paramètres dans l'URL, comme suit:request.getQueryString() semble avoir besoin d'un codage

http://localhost:8080/servlet?param=value 

Lorsque dans le servlet je récupère l'URL, j'ai un problème avec caractères UTF-8. J'utilise ce code:

protected void service(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException { 

     request.setCharacterEncoding("UTF-8"); 

     String reqUrl = request.getRequestURL().toString(); 
     String queryString = request.getQueryString(); 
     System.out.println("Request: "+reqUrl + "?" + queryString); 
     ... 

Donc, si j'appelle cette url:

http://localhost:8080/servlet?param=così 

est comme le résultat ceci:

Request: http://localhost:8080/servlet?param=cos%C3%AC 

Que puis-je faire pour mettre en place correctement la Encodage de caractère?

Répondre

27

J'ai déjà rencontré ce même problème. Vous ne savez pas quel conteneur de servlets Java vous utilisez, mais au moins dans Tomcat 5.x (pas sûr de 6.x), la méthode request.setCharacterEncoding() n'a pas vraiment d'effet sur les paramètres GET. Au moment où votre servlet s'exécute, les paramètres GET ont déjà été décodés par Tomcat, donc setCharacterEncoding ne fera rien.

Deux façons de contourner cela:

  1. Changer le URIEncoding réglage pour votre connecteur en UTF-8. Voir http://tomcat.apache.org/tomcat-5.5-doc/config/http.html. Comme le suggère BalusC, décodez vous-même la chaîne de requête et analysez-la manuellement (plutôt que d'utiliser les API ServletRequest) dans une carte de paramètres.

Espérons que cela aide!

+4

Le paramètre URIEncoding dans # 1 est dans server.xml de Tomcat. Les autres conteneurs de servlets doivent raisonnablement avoir le même type de réglage. – schematic

+1

Pour # 2, vous ne pouvez plus utiliser la méthode request.getParameter(), car cette méthode récupère les paramètres qui ont été décodés de manière incorrecte. Vous devez prendre la chaîne de requête décodée (produite à partir de getQueryString()) et l'analyser manuellement (par exemple, diviser la chaîne par des esperluettes '&' puis diviser les chaînes résultantes par le premier signe égal '='). – schematic

+2

J'ai rencontré un problème avec le paramètre server.xml. Sur les machines Windows, cela fonctionnait correctement, mais sur notre production, les machines basées sur Red Hat Tomcat semblaient ignorer le paramètre server.xml. Nous avons dû implémenter notre propre analyseur de paramètre de requête qui l'a explicitement décodé en utilisant UTF-8. – Herms

28

De l'HttpServletRequest#getQueryString() javadoc:

Retours: une chaîne contenant la chaîne de requête ou null si l'URL contient aucune chaîne de requête. La valeur n'est pas décodée par le conteneur.

Notez la dernière instruction. Donc, vous devez URL-decode vous-même en utilisant java.net.URLDecoder.

String queryString = URLDecoder.decode(request.getQueryString(), "UTF-8"); 

Cependant, la façon normale de recueillir des paramètres est juste en utilisant HttpServletRequest#getParameter().

String param = request.getParameter("param"); // così 

Le servletcontainer a déjà URL décodée pour vous, alors si vous avez configuré pour utiliser le codage correct. Le request.setCharacterEncoding() n'a d'effet que sur le corps de la requête (POST) et non sur l'URI de la requête (GET). Voir aussi la réponse de Mirage.

+0

si j'utilise le URLDecoder ils travaillent, mais quand je veux récupérer uniquement le paramètre avec getParameter(), ils ne fonctionnent pas .. . toute suggestion? – Gabriele

+1

Vous devez définir l'encodage URI du serveur comme expliqué dans Mirage114. Voir aussi [cet article] (http://balusc.blogspot.com/2009/05/unicode-how-to-get-characters-right.html#JSPServletRequest) – BalusC

+1

donc 'getParameter()' appelle 'URLDecoder.decode() 'Quelque part? –

20

Il a vraiment pris toute la journée, mais:

final String param = new String(request.getParameter("param").getBytes(
       "iso-8859-1"), "UTF-8"); 

Voir aussi here.Notez que ceci est valable ssi le charset de décodage (URIEncoding dans tomcat) du serveur est iso-8859-1 -. Sinon ce charset doit être passé dans un exemple de la façon d'obtenir le URIEncoding charset du server.xml pour Tomcat 7 voir mon cité answer

+0

Ceci repose sur le fait que le jeu de caractères par défaut du serveur est UTF-8; au lieu de passer ce charset dans le constructeur de la chaîne. De plus, vous n'avez pas besoin de décoder l'URL de tout ce qui est sorti de 'getParameter'. – bobince

+0

@bobince: vous avez très raison (et je le savais) - je n'avais toujours pas trouvé le temps de passer par mes réponses - édité –

+2

Cela a sauvé ma journée! – NumberFour

1

De nombreux facteurs affectent le codage des paramètres de requête http. vous pouvez référencer le guide séquentiel pour ce problème.

1.Vérifiez que votre formulaire accepte le codage de caractères.

<form id="edit-box" name="edit-box-name" method="post" accept-charset="UTF-8"> 

2. Vérifiez la valeur de codage de caractères par défaut du serveur http. Dans le cas du serveur http apache, ajoutez la chaîne "AddDefaultCharset UTF-8" au fichier httpd.conf.

3.Si vous avez un serveur dorsal, vérifiez la valeur de codage du serveur dorsal. Dans le cas du serveur principal tomcat, ajoutez l'attribut "URIEncoding =" UTF-8" à votre connecteur. Comme,

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

...

guide for http request parameter encoding problems

3

Pour toute demande POST je résolu le problème façon suivante

  1. Set URIEncoding = "UTF-8" attr dans server.xml pour connecteur;. (J'utilise Tomcat 8)
  2. Définissez request.setCharacterEncoding ("UTF-8") avant la récupération des paramètres.

Enfin, j'ai correct delfty-8 caractères: par exemple. String name = request.getParameter ("nom");

Le nom contient la chaîne utf-8 correcte.

-1
pRes.setContentType("text/html; charset=UTF-8"); 
PrintWriter out = new PrintWriter(new (pRes.getOutputStream(), "UTF8"), true); 

En utilisant le code ci-dessus, je suis le résultat attendu :)

Questions connexes