Vybízí to k tomu, abych odpověděl na často kladené otázky tohoto webu. Toto funguje pro mě:
Znaky äåö většinou nejsou problematické, protože výchozí znaková sada používaná prohlížeči a tomcat/java pro webové aplikace je latin1, tzn. ISO-8859-1, která těmto znakům „rozumí“.
Chcete-li, aby UTF-8 fungovalo pod Java+Tomcat+Linux/Windows+Mysql, vyžaduje se následující:
Konfigurace serveru Tomcat.xml
Je nutné nakonfigurovat, aby konektor používal UTF-8 ke kódování parametrů url (požadavek 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"
/>
Klíčovou částí je URIEncoding="UTF-8" ve výše uvedeném příkladu. To zaručuje, že Tomcat zpracovává všechny příchozí parametry GET jako kódování UTF-8. V důsledku toho, když uživatel napíše do adresního řádku prohlížeče následující:
https://localhost:8443/ID/Users?action=search&name=*ж*
znak ж je zpracován jako UTF-8 a je zakódován (obvykle prohlížečem ještě předtím, než se dostane na server) jako %D0%B6 .
Požadavek POST není tímto ovlivněn.
CharsetFilter
Pak je čas přinutit webovou aplikaci Java zpracovávat všechny požadavky a odpovědi jako kódování UTF-8. To vyžaduje, abychom definovali filtr znakové sady, jako je tento:
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() {
}
}
Tento filtr zajišťuje, že pokud prohlížeč nenastavil kódování použité v požadavku, že je nastaveno na UTF-8.
Další věcí, kterou tento filtr dělá, je nastavení výchozího kódování odpovědi, tzn. kódování, ve kterém je vrácený html/whatever. Alternativou je nastavení kódování odezvy atd. v každém ovladači aplikace.
Tento filtr musí být přidán do web.xml nebo deskriptor nasazení webové aplikace:
<!--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>
Pokyny pro vytvoření tohoto filtru naleznete na tomcat wiki ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )
Kódování stránky JSP
Ve vašem web.xml , přidejte následující:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
Případně by všechny JSP stránky webové aplikace musely mít v horní části následující:
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
Pokud se používá nějaký druh rozvržení s různými JSP fragmenty, pak je to potřeba ve všech z nich.
HTML-metaznačky
Kódování stránky JSP říká JVM, aby zpracoval znaky na stránce JSP ve správném kódování. Pak je čas sdělit prohlížeči, ve kterém kódování je stránka html:
To se provádí pomocí následujícího v horní části každé stránky xhtml vytvořené webovou aplikací:
<?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' />
...
Připojení JDBC
Při použití db musí být definováno, že připojení používá kódování UTF-8. To se provádí v context.xml nebo kdekoli, kde je připojení JDBC defend následovně:
<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"
/>
Databáze a tabulky MySQL
Použitá databáze musí používat kódování UTF-8. Toho je dosaženo vytvořením databáze s následujícím:
CREATE DATABASE `ID_development`
/*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;
Poté musí být všechny tabulky také v 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;
Klíčovou částí je CHARSET=utf8 .
Konfigurace serveru MySQL
Je třeba nakonfigurovat také servery MySQL. Obvykle se to ve Windows provádí úpravou my.ini -file a v Linuxu konfigurací my.cnf -file.V těchto souborech by mělo být definováno, že všichni klienti připojení k serveru používají utf8 jako výchozí znakovou sadu a že výchozí znakovou sadu používanou serverem je také utf8.
[client]
port=3306
default-character-set=utf8
[mysql]
default-character-set=utf8
Procedury a funkce Mysql
Tyto také potřebují mít definovanou znakovou sadu. Například:
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 ;
Požadavky GET:latin1 a UTF-8
Pokud a když je v tomcat's server.xml definováno, že parametry požadavku GET jsou kódovány v UTF-8, budou následující požadavky GET zpracovány správně:
https://localhost:8443/ID/Users?action=search&name=Petteri
https://localhost:8443/ID/Users?action=search&name=ж
Protože jsou znaky ASCII kódovány stejným způsobem jak v latin1, tak v UTF-8, je řetězec "Petteri" zpracován správně.
Azbuka ж není v latině vůbec srozumitelná1. Protože je Tomcat instruován, aby zpracovával parametry požadavku jako UTF-8, kóduje tento znak správně jako %D0%B6 .
Pokud a když prohlížeče dostanou pokyn číst stránky v kódování UTF-8 (s záhlavími požadavků a metaznačkou html), alespoň Firefox 2/3 a další prohlížeče z tohoto období kódují znak samy jako %D0% B6 .
Konečným výsledkem je, že jsou nalezeni všichni uživatelé se jménem "Petteri" a také všichni uživatelé se jménem "ж".
Ale co äåö?
Specifikace HTTP definuje, že výchozí adresy URL jsou kódovány jako latin1. Výsledkem je, že firefox2, firefox3 atd. kóduje následující
https://localhost:8443/ID/Users?action=search&name=*Päivi*
do zakódované verze
https://localhost:8443/ID/Users?action=search&name=*P%E4ivi*
V latin1 znak ä je zakódováno jako %E4 . Přestože stránka/požadavek/vše je definováno pro použití UTF-8 . Verze ä s kódováním UTF-8 je %C3%A4
Výsledkem toho je, že je zcela nemožné, aby webová aplikace správně zpracovala parametry požadavku z požadavků GET, protože některé znaky jsou kódovány v latin1 a jiné v UTF-8.Upozornění:Požadavky POST fungují, protože prohlížeče kódují všechny parametry požadavku z formulářů zcela v UTF-8, pokud je stránka definována jako UTF-8
Věci ke čtení
Velmi děkuji autorům následujícího článku za odpovědi na můj problém:
- 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/
Důležitá poznámka
mysql
podporuje Základní vícejazyčnou rovinu
pomocí 3bajtových znaků UTF-8. Pokud potřebujete jít mimo (některé abecedy vyžadují více než 3 bajty UTF-8), musíte buď použít variantu VARBINARY
typ sloupce nebo použijte utf8mb4 znaková sada
(což vyžaduje MySQL 5.5.3 nebo novější). Jen si uvědomte, že pomocí utf8
znaková sada v MySQL nebude fungovat 100 % času.
Tomcat s Apache
Ještě jedna věc Pokud používáte konektor Apache + Tomcat + mod_JK, musíte také provést následující změny:
- Přidejte URIEncoding="UTF-8" do souboru tomcat server.xml pro konektor 8009, používá ho konektor mod_JK.
- Přejděte do složky Apache, tj.
/etc/httpd/conf
a přidejteAddDefaultCharset utf-8
vsouboru httpd.conf
. Poznámka: Nejprve zkontrolujte, zda existuje nebo ne. Pokud existuje, můžete jej aktualizovat pomocí tohoto řádku. Tento řádek můžete také přidat na konec.