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?
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&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
mysql 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:
- 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"/>
- allez dans votre dossier apache i.e.
/etc/httpd/conf
et ajoutezAddDefaultCharset utf-8
danshttpd.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.
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.)
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>
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.....
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.
-
tapez "about:config" dans la barre d'adresse.
-
utilisez le type d'entrée filter pour rechercher" network.standard-url.encoder-requête-utf8" de la propriété.
- la propriété ci-dessus sera false par défaut, turn that to TRUE.
- redémarrez le navigateur.
l'encodage UTF-8 sur les Url qui fonctionne par défaut dans IE6/7/8 et google chrome.
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 ;)
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".
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.
à 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+)
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.
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-8export LANGUAGE=en_US.UTF-8
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");