Comment faire pour que UTF-8 fonctionne sur les webapps Java?

je dois faire fonctionner UTF-8 dans mon Java webapp (servlets + JSP, pas de framework utilisé) pour prendre en charge äöå etc. pour les textes finnois réguliers et les alphabets cyrilliques comme ЦжФ pour les cas spéciaux.

mon installation est la suivante:

  • environnement de développement: Windows XP
  • environnement de Production: Debian

base de données utilisée: MySQL 5.x

utilisateurs utilisez principalement Firefox2 mais aussi Opera 9.x, FF3, IE7 et Google Chrome sont utilisés pour accéder au site.

comment y parvenir?

346
demandé sur informatik01 2008-09-26 15:48:09

13 réponses

répondre à moi-même comme la FAQ de ce site l'encourage. Cela fonctionne pour moi:

la plupart du temps les caractères äåö ne sont pas un problème car le jeu de caractères par défaut utilisé par les navigateurs et tomcat/java pour webapps est latin1 ie. ISO-8859-1 qui "comprend" ces caractères.

pour que UTF-8 fonctionne sous Java+Tomcat+Linux / Windows+Mysql nécessite ce qui suit:

configurer Tomcat serveur.xml

il est nécessaire de configurer que le connecteur utilise UTF-8 pour encoder les paramètres url (GET request):

<Connector port="8080" maxHttpHeaderSize="8192"
 maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
 enableLookups="false" redirectPort="8443" acceptCount="100"
 connectionTimeout="20000" disableUploadTimeout="true" 
 compression="on" 
 compressionMinSize="128" 
 noCompressionUserAgents="gozilla, traviata" 
 compressableMimeType="text/html,text/xml,text/plain,text/css,text/ javascript,application/x-javascript,application/javascript"
 URIEncoding="UTF-8"
/>

la partie clé étant URIEncoding=" UTF-8 " dans l'exemple ci-dessus. Cette quarantaine que Tomcat gère tous les paramètres entrants sont encodés en UTF-8. En conséquence, lorsque l'utilisateur écrit ce qui suit dans la barre d'adresse du navigateur:

 https://localhost:8443/ID/Users?action=search&name=*ж*

le personnage est géré comme UTF-8 et est encodé à (Généralement par le navigateur avant même d'arriver au serveur) comme %D0%B6 .

requête POST ne sont pas affectés par cette.

CharsetFilter

puis il est temps de forcer le java webapp à traiter toutes les requêtes et réponses comme encodé UTF-8. Cela nécessite que nous définissions un filtre de jeu de caractères comme suit:

package fi.foo.filters;

import javax.servlet.*;
import java.io.IOException;

public class CharsetFilter implements Filter {

    private String encoding;

    public void init(FilterConfig config) throws ServletException {
        encoding = config.getInitParameter("requestEncoding");
        if (encoding == null) encoding = "UTF-8";
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain next)
            throws IOException, ServletException {
        // Respect the client-specified character encoding
        // (see HTTP specification section 3.4.1)
        if (null == request.getCharacterEncoding()) {
            request.setCharacterEncoding(encoding);
        }

        // Set the default response content type and encoding
        response.setContentType("text/html; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");

        next.doFilter(request, response);
    }

    public void destroy() {
    }
}

ce filtre s'assure que si le navigateur n'a pas paramétré l'encodage utilisé dans la requête, il est paramétré à UTF-8.

l'autre chose faite par ce filtre est de définir la réponse par défaut encodage ie. l'encodage dans lequel le html/Tout ce qui est renvoyé est. L'alternative est de définir l'encodage de la réponse, etc. dans chaque contrôleur de l'application.

Ce filtre doit être ajouté à la "1519350920 web".xml ou le descripteur de déploiement de la webapp:

 <!--CharsetFilter start--> 

  <filter>
    <filter-name>CharsetFilter</filter-name>
    <filter-class>fi.foo.filters.CharsetFilter</filter-class>
      <init-param>
        <param-name>requestEncoding</param-name>
        <param-value>UTF-8</param-value>
      </init-param>
  </filter>

  <filter-mapping>
    <filter-name>CharsetFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

les instructions pour fabriquer ce filtre se trouvent sur le wiki de tomcat ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )

JSP le codage de la page

dans votre web.xml , ajouter le texte suivant:

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

alternativement, toutes les pages JSP de la webapp devraient avoir en haut d'eux:

 <%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>

si une sorte de mise en page avec différents fragments JSP est utilisée, alors cela est nécessaire dans tous d'entre eux.

HTML-balises meta

l'encodage de la page JSP indique à la JVM de gérer les caractères de la page JSP dans le bon encodage. Ensuite, il est temps de dire au navigateur dans lequel encoder la page html est:

C'est fait avec ce qui suit en haut de chaque page xhtml produit par le webapp:

   <?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
   <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fi">
   <head>
   <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
   ...

JDBC-connection

Lorsqu'on utilise une db, il faut définir que la connexion utilise L'encodage UTF-8. Cela se fait dans le contexte .xml ou chaque fois que la connexion JDBC est définie comme suit:

      <Resource name="jdbc/AppDB" 
        auth="Container"
        type="javax.sql.DataSource"
        maxActive="20" maxIdle="10" maxWait="10000"
        username="foo"
        password="bar"
        driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/      ID_development?useEncoding=true&amp;characterEncoding=UTF-8"
    />

MySQL base de données et des tables

la base de données utilisée doit utiliser L'encodage UTF-8. Pour ce faire, on crée la base de données avec ce qui suit:

   CREATE DATABASE `ID_development` 
   /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;

ensuite, tous les tableaux doivent être en UTF-8 aussi:

   CREATE TABLE  `Users` (
    `id` int(10) unsigned NOT NULL auto_increment,
    `name` varchar(30) collate utf8_swedish_ci default NULL
    PRIMARY KEY  (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci ROW_FORMAT=DYNAMIC;

la partie clé étant CHARSET=utf8 .

configuration du serveur MySQL

MySQL serveri doit aussi être configuré. Typiquement Ceci est fait dans Windows en modifiant my.ini - fichier et sous Linux par la configuration de mon.cnf -fichier. Dans ces fichiers, il doit être défini que tous les clients connectés au serveur utilisent utf8 comme jeu de caractères par défaut et que le jeu de caractères par défaut utilisé par le serveur est aussi utf8.

   [client]
   port=3306
   default-character-set=utf8

   [mysql]
   default-character-set=utf8

Mysql les procédures et les fonctions

ceux-ci doivent aussi avoir le jeu de caractères défini. Par exemple:

   DELIMITER $$

   DROP FUNCTION IF EXISTS `pathToNode` $$
   CREATE FUNCTION `pathToNode` (ryhma_id INT) RETURNS TEXT CHARACTER SET utf8
   READS SQL DATA
   BEGIN

    DECLARE path VARCHAR(255) CHARACTER SET utf8;

   SET path = NULL;

   ...

   RETURN path;

   END $$

   DELIMITER ;

les requêtes GET: latin1 et UTF-8

si et quand il est défini dans le serveur de tomcat.xml que les paramètres des requêtes GET sont encodés en UTF-8, les requêtes GET suivantes sont traitées correctement:

   https://localhost:8443/ID/Users?action=search&name=Petteri
   https://localhost:8443/ID/Users?action=search&name=ж

parce que les caractères ASCII sont encodés de la même manière avec latin1 et UTF-8, la chaîne" Petteri " est manipulée correctement.

en latin1, le caractère Cyrillique de ❚ n'est pas compris du tout. Parce que Tomcat est chargé de traiter les paramètres de requête comme UTF-8 il encode ce caractère est correctement %D0 % B6 .

si et quand les navigateurs reçoivent l'instruction de lire les pages dans L'encodage UTF-8 (avec en-tête de requête et méta-étiquette html), au moins Firefox 2/3 et les autres navigateurs de cette période encodent tous le caractère eux-mêmes comme %D0%B6 .

Le résultat final est que tous les utilisateurs avec le nom "Petteri" sont disponibles et également à tous les utilisateurs avec le nom "ж" trouvés.

mais qu'en est-il äåö?

HTTP-specification définit que par défaut les URLs sont encodées en latin1. Il en résulte des firefox2, firefox3 etc. codant pour la suite

    https://localhost:8443/ID/Users?action=search&name=*Päivi*

dans la version codée

    https://localhost:8443/ID/Users?action=search&name=*P%E4ivi*

En latin1 le caractère ä est codé comme %E4 . même si la page / requête / tout est défini pour utiliser UTF-8 . La version codée UTF-8 de ä est % C3%A4

il en résulte qu'il est tout à fait impossible pour le webapp de gérer correctement les paramètres de requête des requêtes GET car certains caractères sont encodés en latin1 et d'autres en UTF-8. remarque: les requêtes POST faire un travail que les navigateurs coder tous les paramètres de la requête à partir de formes entièrement en UTF-8 si la page est définie comme étant l'UTF-8

un très grand merci pour les rédacteurs des suivants pour avoir donné les réponses à mon problème:

  • http://tagunov.tripod.com/i18n/i18n.html
  • http://wiki.apache.org/tomcat/Tomcat/UTF-8
  • http://java.sun.com/developer/technicalArticles/Intl/HTTPCharset /
  • http://dev.mysql.com/doc/refman/5.0/en/charset-syntax.html
  • http://cagan327.blogspot.com/2006/05/utf-8-encoding-fix-tomcat-jsp-etc.html
  • http://cagan327.blogspot.com/2006/05/utf-8-encoding-fix-for-mysql-tomcat.html
  • http://jeppesn.dk/utf-8.html
  • http://www.nabble.com/request-parameters-mishandle-utf-8-encoding-td18720039.html
  • http://www.utoronto.ca/webdocs/HTMLdocs/NewHTML/iso_table.html
  • http://www.utf8-chartable.de /

Note Importante

supporte le plan de base multilingue en utilisant 3 octets UTF-8 caractères. Si vous avez besoin d'aller en dehors de cela( certains alphabets exigent plus de 3-bytes de UTF-8), alors vous avez besoin d'utiliser une saveur de VARBINARY type de colonne ou d'utiliser le utf8mb4 jeu de caractères (qui nécessite MySQL 5.5.3 ou plus tard). Il suffit d'être conscient que l'utilisation du caractère utf8 défini dans MySQL ne fonctionnera pas 100% du temps.

Tomcat Apache

une dernière chose si vous utilisez Apache + Tomcat + mod_JK connector, vous devez aussi effectuer les changements suivants:

  1. ajouter URIEncoding=" UTF-8 " dans tomcat server.fichier xml pour le connecteur 8009, il est utilisé par le connecteur mod_JK. <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
  2. allez dans votre dossier apache i.e. /etc/httpd/conf et ajoutez AddDefaultCharset utf-8 dans httpd.conf file . Note: vérifier D'abord qu'il existe ou non. S'il existe, Vous pouvez le mettre à jour avec cette ligne. Vous pouvez ajouter cette ligne à bas aussi.
528
répondu kosoant 2018-08-11 16:07:44

je pense que vous l'avez très bien résumé dans votre propre réponse.

Dans le processus de l'UTF-8-ing(?) de bout en bout, vous pouvez également vous assurer que java lui-même utilise UTF-8. Use-Dfile.encoding=utf-8 comme paramètre de la JVM (peut être configuré en catalina.chauve.)

12
répondu stian 2008-09-27 21:54:08

ajouter À kosoant la réponse de , si vous êtes à l'aide de Printemps, plutôt que d'écrire votre propre filtre de Servlet, vous pouvez utiliser la classe org.springframework.web.filter.CharacterEncodingFilter qu'ils fournissent, une configuration comme celle-ci dans votre site web.xml:

 <filter>
    <filter-name>encoding-filter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
       <param-name>encoding</param-name>
       <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
       <param-name>forceEncoding</param-name>
       <param-value>FALSE</param-value>
    </init-param>
 </filter>
 <filter-mapping>
    <filter-name>encoding-filter</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>
9
répondu Raedwald 2017-05-23 10:31:13

C'est pour L'encodage grec dans les tables MySql quand on veut y accéder en utilisant Java:

utilisez la configuration de connexion suivante dans votre pool de connexion JBoss (mysql-ds.xml)

<connection-url>jdbc:mysql://192.168.10.123:3308/mydatabase</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>nts</user-name>
<password>xaxaxa!</password>
<connection-property name="useUnicode">true</connection-property>
<connection-property name="characterEncoding">greek</connection-property>

si vous ne voulez pas le mettre dans un pool de connexion JNDI, vous pouvez le configurer comme JDBC-url comme l'illustre la ligne suivante:

jdbc:mysql://192.168.10.123:3308/mydatabase?characterEncoding=greek

pour Nick et moi, pour qu'on ne l'oublie jamais et qu'on ne perde plus de temps.....

1
répondu Mike Mountrakis 2009-12-04 13:52:33

belle réponse détaillée. je voulais juste ajouter une chose qui aidera certainement les autres à voir L'encodage UTF-8 sur les URLs en action .

suivez les étapes ci-dessous pour activer L'encodage UTF-8 sur les URLs dans firefox.

  1. tapez "about:config" dans la barre d'adresse.

  2. utilisez le type d'entrée filter pour rechercher" network.standard-url.encoder-requête-utf8" de la propriété.

  3. la propriété ci-dessus sera false par défaut, turn that to TRUE.
  4. redémarrez le navigateur.

l'encodage UTF-8 sur les Url qui fonctionne par défaut dans IE6/7/8 et google chrome.

1
répondu Jay 2010-02-19 01:30:34

je veux aussi ajouter de ici cette partie a résolu mon problème utf:

runtime.encoding=<encoding>
1
répondu John 2013-01-15 02:19:46

je suis avec un problème similaire, mais, dans les noms de fichiers d'un fichier je comprime avec apache commons. Donc, je l'ai résolu avec cette commande:

convmv --notest -f cp1252 -t utf8 * -r

ça marche très bien pour moi. Espérons que cela aide quelqu'un ;)

0
répondu caarlos0 2011-07-20 13:45:30

pour mon cas d'affichage de caractères Unicode à partir de paquets de messages, je n'ai pas besoin d'appliquer la section" encodage de page JSP " pour afficher Unicode sur ma page jsp. Tout ce dont j'ai besoin c'est de la section" CharsetFilter".

0
répondu bnguyen82 2012-06-21 01:59:03

un autre point qui n'a pas été mentionné concerne les Servlets Java travaillant avec Ajax. J'ai des situations où une page Web reçoit du texte utf-8 de l'utilisateur qui l'envoie à un fichier JavaScript qui l'inclut dans un URI envoyé au Servlet. Le Servlet interroge une base de données, saisit le résultat et le renvoie en XML au fichier JavaScript qui le formate et insère la réponse formatée dans la page Web originale.

dans une application web Je suivais un les premières instructions D'Ajax book pour envelopper le JavaScript dans la construction de L'URI. L'exemple dans le livre utilisé la méthode escape (), que j'ai découvert (à la dure) est erroné. Pour utf-8, vous devez utiliser encodeURIComponent().

peu de gens semblent rouler leur propre Ajax ces jours-ci, mais j'ai pensé que je pourrais aussi bien ajouter ceci.

0
répondu David 2015-11-14 22:30:51

à propos de CharsetFilter mentionné dans la réponse de @kosoant ....

il y a une construction dans Filter dans tomcat web.xml (situé à conf/web.xml ). Le filtre s'appelle setCharacterEncodingFilter et est commenté par défaut. Vous pouvez décommenter cela ( s'il vous plaît se rappeler de décommenter son filter-mapping trop)

il n'est pas non plus nécessaire de définir jsp-config dans votre web.xml (Je l'ai testé pour Tomcat 7+)

0
répondu Alireza Fattahi 2017-01-09 05:24:48

un certain temps, vous pouvez résoudre le problème par MySQL Administrateur assistant. In

variables de démarrage > avancées >

et set Def. jeu de caractères: utf8

peut-être que cette configuration a besoin de redémarrer MySQL.

0
répondu user3600935 2017-07-13 18:34:13

les réponses précédentes n'ont pas fonctionné avec mon problème. Il était seulement en production, avec tomcat et apache mod_proxy_ajp. Post corps perdu non ascii caractères ? Le problème est finalement apparu avec JVM defaultCharset (US-ASCII dans une installation par défaut: Charset dfset = Charset.defaultCharset();) ainsi, la solution a été d'exécuter tomcat server avec un modificateur pour exécuter la JVM avec UTF-8 comme jeu de caractères par défaut:

JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8" 

(ajouter cette ligne à catalina.sh et service tomcat redémarrage)

peut-être que vous devez aussi changer la variable système linux (edit ~/.bashrc et ~/.profil pour changement permanent, voir https://perlgeek.de/en/article/set-up-a-clean-utf8-environment )

export LC_ALL=en_US.UTF-8

export LANG=en_US.UTF-8

export LANGUAGE=en_US.UTF-8

0
répondu Rogelio 2018-04-17 06:18:01

dans le cas où vous avez spécifié dans connection pool (mysql-ds.xml), dans votre code Java, vous pouvez ouvrir la connexion comme suit:

DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Connection conn = DriverManager.getConnection(
    "jdbc:mysql://192.168.1.12:3308/mydb?characterEncoding=greek",
    "Myuser", "mypass");
-1
répondu Mike Mountrakis 2011-10-09 12:42:41