Rispondere a me stesso come le FAQ di questo sito lo incoraggiano. Questo funziona per me:
Per lo più i caratteri äåö non sono problematici in quanto il set di caratteri predefinito utilizzato dai browser e tomcat / java per webapps è latino1, ad esempio. ISO-8859-1 che "comprende" quei personaggi.
Per far funzionare UTF-8 su Java + Tomcat + Linux / Windows + Mysql è necessario quanto segue:
Configurazione di server.xml di Tomcat
È necessario configurare che il connettore usi UTF-8 per codificare i parametri url (richiesta GET):
<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 parte chiave è URIEncoding = "UTF-8" nell'esempio sopra. Ciò garantisce che Tomcat gestisce tutti i parametri GET in entrata con codifica UTF-8. Di conseguenza, quando l'utente scrive quanto segue nella barra degli indirizzi del browser:
https://localhost:8443/ID/Users?action=search&name=*ж*
il carattere ж è gestito come UTF-8 ed è codificato (di solito dal browser prima ancora di arrivare al server) come % D0% B6 .
La richiesta POST non è interessata da questo.
CharsetFilter
Quindi è il momento di forzare la webapp java a gestire tutte le richieste e le risposte come codificate UTF-8. Ciò richiede che definiamo un filtro set di caratteri come il seguente:
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() {
}
}
Questo filtro si assicura che se il browser non ha impostato la codifica utilizzata nella richiesta, sia impostato su UTF-8.
L'altra cosa fatta da questo filtro è impostare la codifica della risposta predefinita, ad es. la codifica in cui l'html restituito / qualunque sia. L'alternativa è impostare la codifica della risposta ecc. In ciascun controller dell'applicazione.
Questo filtro deve essere aggiunto a web.xml o al descrittore di distribuzione della 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>
Le istruzioni per creare questo filtro sono disponibili nel wiki tomcat ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )
Codifica della pagina JSP
Nel tuo web.xml , aggiungi quanto segue:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
In alternativa, tutte le pagine JSP della webapp dovrebbero avere le seguenti in cima:
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
Se viene utilizzato un tipo di layout con frammenti JSP diversi, ciò è necessario in tutti .
Meta-tag HTML
La codifica della pagina JSP indica a JVM di gestire i caratteri nella pagina JSP nella codifica corretta. Quindi è tempo di dire al browser in quale codifica la pagina html è:
Questo viene fatto con quanto segue nella parte superiore di ogni pagina xhtml prodotta dalla 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
Quando si utilizza un db, è necessario definire che la connessione utilizza la codifica UTF-8. Questo viene fatto in context.xml o ovunque la connessione JDBC sia definita come segue:
<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"
/>
Database e tabelle MySQL
Il database utilizzato deve utilizzare la codifica UTF-8. Ciò si ottiene creando il database con quanto segue:
CREATE DATABASE `ID_development`
/*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;
Quindi, tutte le tabelle devono essere anche in UTF-8:
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 parte chiave è CHARSET = utf8 .
Configurazione del server MySQL
Anche il server MySQL deve essere configurato. In genere ciò avviene in Windows modificando my.ini -file e in Linux configurando my.cnf -file. In questi file è necessario definire che tutti i client connessi al server utilizzano utf8 come set di caratteri predefinito e che anche il set di caratteri predefinito utilizzato dal server è utf8.
[client]
port=3306
default-character-set=utf8
[mysql]
default-character-set=utf8
Procedure e funzioni di Mysql
Anche questi devono avere il set di caratteri definito. Per esempio:
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 ;
Ricevi richieste: latin1 e UTF-8
Se e quando è definito in server.xml di tomcat che i parametri della richiesta GET sono codificati in UTF-8, le seguenti richieste GET vengono gestite correttamente:
https://localhost:8443/ID/Users?action=search&name=Petteri
https://localhost:8443/ID/Users?action=search&name=ж
Poiché i caratteri ASCII sono codificati allo stesso modo sia con latin1 che con UTF-8, la stringa "Petteri" viene gestita correttamente.
Il carattere cirillico ж non è affatto compreso in latino1. Poiché a Tomcat viene richiesto di gestire i parametri di richiesta come UTF-8, codifica quel carattere correttamente come % D0% B6 .
Se e quando viene richiesto ai browser di leggere le pagine in codifica UTF-8 (con intestazioni di richiesta e metatag html), almeno Firefox 2/3 e altri browser di questo periodo codificano tutti il carattere come % D0% B6 .
Il risultato finale è che sono stati trovati tutti gli utenti con il nome "Petteri" e anche tutti gli utenti con il nome "ж".
Ma che dire di äåö?
La specifica HTTP definisce che per impostazione predefinita gli URL sono codificati come latin1. Ciò comporta firefox2, firefox3 ecc. Che codifica quanto segue
https://localhost:8443/ID/Users?action=search&name=*Päivi*
nella versione codificata
https://localhost:8443/ID/Users?action=search&name=*P%E4ivi*
In latino1 il carattere ä è codificato come % E4 . Anche se la pagina / richiesta / tutto è definito per usare UTF-8 . La versione codificata UTF-8 di ä è % C3% A4
Il risultato di ciò è che è impossibile per la webapp gestire correttamente i parametri di richiesta dalle richieste GET poiché alcuni caratteri sono codificati in latino1 e altri in UTF-8.
Avviso: le richieste POST funzionano poiché i browser codificano tutti i parametri di richiesta dai moduli completamente in UTF-8 se la pagina è definita come UTF-8
Roba da leggere
Un grande ringraziamento per gli autori di quanto segue per aver dato le risposte al mio problema:
- 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/
Nota importante
mysqlsupporta il piano multilingue di base utilizzando caratteri UTF-8 a 3 byte. Se è necessario uscire da questo (alcuni alfabeti richiedono più di 3 byte di UTF-8), è necessario utilizzare un VARBINARY
tipo di colonna o utilizzare il utf8mb4
set di caratteri (che richiede MySQL 5.5.3 o successivo). Basta essere consapevoli del fatto che l'utilizzo del utf8
set di caratteri in MySQL non funzionerà il 100% delle volte.
Tomcat con Apache
Un'altra cosa Se si utilizza il connettore Apache + Tomcat + mod_JK, è necessario eseguire anche le seguenti modifiche:
- Aggiungi URIEncoding = "UTF-8" nel file tomcat server.xml per il connettore 8009, viene utilizzato dal connettore mod_JK.
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
- Goto vostro apache cartella cioè
/etc/httpd/conf
e aggiungere AddDefaultCharset utf-8
in httpd.conf file
. Nota: verificare innanzitutto che esista o meno. Se esiste, puoi aggiornarlo con questa riga. Puoi anche aggiungere questa riga in fondo.