Responder a mim mesmo como o FAQ deste site o encoraja. Isso funciona para mim:
Principalmente os caracteres äåö não são problemáticos, pois o conjunto de caracteres padrão usado pelos navegadores e o tomcat / java para webapps é latin1, ie. ISO-8859-1, que "entende" esses caracteres.
Para que o UTF-8 funcione em Java + Tomcat + Linux / Windows + Mysql, é necessário o seguinte:
Configurando o server.xml do Tomcat
É necessário configurar que o conector use UTF-8 para codificar os parâmetros de URL (solicitação 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"
/>
A parte principal sendo URIEncoding = "UTF-8" no exemplo acima. Isso garante que o Tomcat lide com todos os parâmetros GET recebidos como codificados em UTF-8. Como resultado, quando o usuário grava o seguinte na barra de endereços do navegador:
https://localhost:8443/ID/Users?action=search&name=*ж*
o caractere ж é tratado como UTF-8 e é codificado para (geralmente pelo navegador antes mesmo de chegar ao servidor) como % D0% B6 .
A solicitação POST não é afetada por isso.
CharsetFilter
Chegou a hora de forçar o java webapp a lidar com todos os pedidos e respostas conforme codificado em UTF-8. Isso requer que definamos um filtro de conjunto de caracteres como o seguinte:
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() {
}
}
Esse filtro garante que, se o navegador não tiver definido a codificação usada na solicitação, esteja definido como UTF-8.
A outra coisa feita por esse filtro é definir a codificação de resposta padrão, ou seja. a codificação na qual o html retornado / o que quer que seja. A alternativa é definir a codificação da resposta etc. em cada controlador do aplicativo.
Esse filtro deve ser adicionado ao web.xml ou ao descritor de implementação do aplicativo da web:
<!--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>
As instruções para criar esse filtro são encontradas no wiki do tomcat ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 )
Codificação de página JSP
No seu web.xml , adicione o seguinte:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
Como alternativa, todas as páginas JSP do aplicativo da web precisariam ter o seguinte na parte superior:
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
Se algum tipo de layout com fragmentos JSP diferentes for usado, isso será necessário em todos eles.
Meta tags HTML
A codificação de página JSP informa à JVM para manipular os caracteres na página JSP na codificação correta. Chegou a hora de informar ao navegador em que codificação a página html está:
Isso é feito com o seguinte na parte superior de cada página xhtml produzida pelo aplicativo da web:
<?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' />
...
Conexão JDBC
Ao usar um banco de dados, é necessário definir que a conexão use a codificação UTF-8. Isso é feito no context.xml ou onde quer que a conexão JDBC seja desativada da seguinte maneira:
<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"
/>
Banco de dados MySQL e tabelas
O banco de dados usado deve usar a codificação UTF-8. Isso é alcançado criando o banco de dados com o seguinte:
CREATE DATABASE `ID_development`
/*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;
Em seguida, todas as tabelas também precisam estar em 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;
A parte principal sendo CHARSET = utf8 .
Configuração do servidor MySQL
O servidor MySQL também deve ser configurado. Normalmente, isso é feito no Windows, modificando o arquivo my.ini e no Linux, configurando o arquivo my.cnf . Nesses arquivos, deve-se definir que todos os clientes conectados ao servidor usem utf8 como o conjunto de caracteres padrão e que o conjunto de caracteres padrão usado pelo servidor também seja utf8.
[client]
port=3306
default-character-set=utf8
[mysql]
default-character-set=utf8
Procedimentos e funções Mysql
Eles também precisam ter o conjunto de caracteres definido. Por exemplo:
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 ;
Solicitações GET: latin1 e UTF-8
Se e quando for definido no server.xml do tomcat que os parâmetros de solicitação GET sejam codificados em UTF-8, as seguintes solicitações GET serão tratadas adequadamente:
https://localhost:8443/ID/Users?action=search&name=Petteri
https://localhost:8443/ID/Users?action=search&name=ж
Como os caracteres ASCII são codificados da mesma maneira com latin1 e UTF-8, a sequência "Petteri" é manipulada corretamente.
O caráter cirílico ж não é totalmente compreendido em latim1. Como o Tomcat é instruído a manipular parâmetros de solicitação como UTF-8, ele codifica esse caractere corretamente como % D0% B6 .
Se e quando os navegadores forem instruídos a ler as páginas na codificação UTF-8 (com cabeçalhos de solicitação e metatag html), pelo menos o Firefox 2/3 e outros navegadores desse período codificarão o caractere como % D0% B6 .
O resultado final é que todos os usuários com o nome "Petteri" são encontrados e também todos os usuários com o nome "ж".
Mas e quanto a äåö?
A especificação HTTP define que, por padrão, os URLs são codificados como latin1. Isso resulta no firefox2, firefox3 etc., codificando os seguintes
https://localhost:8443/ID/Users?action=search&name=*Päivi*
para a versão codificada
https://localhost:8443/ID/Users?action=search&name=*P%E4ivi*
Em latin1, o caractere ä é codificado como % E4 . Mesmo que a página / solicitação / tudo esteja definido para usar UTF-8 . A versão codificada em UTF-8 de ä é % C3% A4
O resultado disso é que é praticamente impossível para o aplicativo da web manipular corretamente os parâmetros de solicitação GET, pois alguns caracteres são codificados em latin1 e outros em UTF-8.
Aviso: solicitações POST funcionam como navegadores codificam todos os parâmetros de solicitação de formulários completamente em UTF-8 se a página for definida como sendo UTF-8
Coisas para ler
Muito obrigado pelos escritores a seguir por dar as respostas para o meu 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
mysqlsuporta o plano multilíngue básico usando caracteres UTF-8 de 3 bytes. Se você precisar ir além disso (determinados alfabetos requerem mais de 3 bytes de UTF-8), será necessário usar um VARBINARY
tipo de coluna ou usar o utf8mb4
conjunto de caracteres (que requer o MySQL 5.5.3 ou posterior). Lembre-se de que o uso do utf8
conjunto de caracteres no MySQL não funcionará 100% do tempo.
Tomcat com Apache
Mais uma coisa Se você estiver usando o conector Apache + Tomcat + mod_JK, também precisará fazer as seguintes alterações:
- Inclua URIEncoding = "UTF-8" no arquivo tomcat server.xml para o conector 8009, que é usado pelo conector mod_JK.
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
- Vá para a pasta apache, ou seja,
/etc/httpd/conf
adicione AddDefaultCharset utf-8
-a httpd.conf file
. Nota: Primeiro verifique se existe ou não. Se existir, você pode atualizá-lo com esta linha. Você pode adicionar esta linha na parte inferior também.