Отвечая на себя как часто задаваемые вопросы этого сайта поощряет это. Это работает для меня:
В основном, символы не являются проблематичными, поскольку набор символов по умолчанию, используемый браузерами, а tomcat / java для веб-приложений - latin1, т.е. ISO-8859-1, который "понимает" эти символы.
Для работы UTF-8 под Java + Tomcat + Linux / Windows + Mysql требуется следующее:
Конфигурирование сервера Tomcat server.xml
Необходимо настроить, чтобы соединитель использовал UTF-8 для кодирования параметров 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"
/>
Ключевой частью является URIEncoding = "UTF-8" в вышеприведенном примере. Это гарантирует, что Tomcat обрабатывает все входящие параметры GET в кодировке UTF-8. В результате, когда пользователь пишет в адресную строку браузера следующее:
https://localhost:8443/ID/Users?action=search&name=*ж*
символ is обрабатывается как UTF-8 и кодируется (обычно браузером перед тем, как даже попасть на сервер) как % D0% B6 .
На запрос POST это не влияет.
CharsetFilter
Затем пришло время заставить приложение Java обрабатывать все запросы и ответы в кодировке UTF-8. Для этого необходимо определить фильтр набора символов следующим образом:
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() {
}
}
Этот фильтр гарантирует, что если браузер не установил кодировку, используемую в запросе, он установлен в UTF-8.
Другая вещь, которую делает этот фильтр, заключается в установке кодировки ответа по умолчанию, т.е. кодировка, в которой возвращается html / что угодно. Альтернативой является установка кодировки ответа и т. Д. В каждом контроллере приложения.
Этот фильтр необходимо добавить в файл web.xml или дескриптор развертывания веб-приложения:
<!--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>
Инструкции по созданию этого фильтра можно найти на вики tomcat ( http://wiki.apache.org/tomcat/Tomcat/UTF-8 ).
JSP кодирование страницы
В вашем web.xml добавьте следующее:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
В качестве альтернативы, на всех JSP-страницах веб-приложения должно быть следующее:
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
Если используется какая-то компоновка с разными JSP-фрагментами, то это необходимо во всех из них.
HTML-мета-теги
Кодировка страницы JSP говорит JVM обрабатывать символы на странице JSP в правильной кодировке. Затем пришло время сообщить браузеру, в какой кодировке находится HTML-страница:
Это делается с помощью следующего в верхней части каждой HTML-страницы, созданной веб-приложением:
<?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-соединение
При использовании БД необходимо определить, что соединение использует кодировку UTF-8. Это делается в context.xml или там, где соединение JDBC определяется следующим образом:
<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 база данных и таблицы
Используемая база данных должна использовать кодировку UTF-8. Это достигается путем создания базы данных со следующим:
CREATE DATABASE `ID_development`
/*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;
Затем все таблицы должны быть в 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;
Ключевой частью является CHARSET = utf8 .
Конфигурация сервера MySQL
MySQL serveri также должен быть настроен. Обычно это делается в Windows путем изменения my.ini -file, а в Linux - путем настройки my.cnf -file. В этих файлах должно быть определено, что все клиенты, подключенные к серверу, используют utf8 в качестве набора символов по умолчанию и что набор символов по умолчанию, используемый сервером, также является utf8.
[client]
port=3306
default-character-set=utf8
[mysql]
default-character-set=utf8
Mysql процедуры и функции
Они также должны иметь определенный набор символов. Например:
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 ;
GET запросы: latin1 и UTF-8
Если и когда в tomcat server.xml определено, что параметры запроса GET кодируются в UTF-8, следующие запросы GET обрабатываются правильно:
https://localhost:8443/ID/Users?action=search&name=Petteri
https://localhost:8443/ID/Users?action=search&name=ж
Поскольку ASCII-символы кодируются одинаково как с помощью latin1, так и UTF-8, строка «Petteri» обрабатывается правильно.
Символ кириллицы ж вообще не понимается в латинице1. Поскольку Tomcat получает указание обрабатывать параметры запроса как UTF-8, он правильно кодирует этот символ как % D0% B6 .
Если и когда браузеры проинструктированы читать страницы в кодировке UTF-8 (с заголовками запросов и метатегом html), по крайней мере, Firefox 2/3 и другие браузеры этого периода сами кодируют символ как % D0% B6 .
Конечным результатом является то, что все пользователи с именем "Petteri" найдены, а также все пользователи с именем "ж" найдены.
Но как насчет?
HTTP-спецификация определяет, что по умолчанию URL кодируются как latin1. Это приводит к тому, что firefox2, firefox3 и т. Д. Кодируют следующее
https://localhost:8443/ID/Users?action=search&name=*Päivi*
в зашифрованной версии
https://localhost:8443/ID/Users?action=search&name=*P%E4ivi*
В латинице 1 символ ä кодируется как % E4 . Хотя страница / запрос / все определено для использования UTF-8 . Версия ä в кодировке UTF-8: % C3% A4
В результате этого веб-приложение не может корректно обрабатывать параметры запроса из запросов GET, поскольку некоторые символы кодируются в латинице 1, а другие - в UTF-8.
Примечание: запросы POST работают, так как браузеры полностью кодируют все параметры запроса из форм в UTF-8, если страница определена как UTF-8.
Материал для чтения
Большое спасибо авторам следующих статей за ответы на мою проблему:
- 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/
Важная заметка
MySQLподдерживает базовую многоязычную плоскость, используя 3-байтовые символы UTF-8. Если вам нужно выйти за пределы этого (некоторые алфавиты требуют более 3 байтов UTF-8), то вам нужно либо использовать VARBINARY
тип столбца, либо использовать utf8mb4
набор символов (для этого требуется MySQL 5.5.3 или более поздняя версия). Просто помните, что использование utf8
набора символов в MySQL не будет работать 100% времени.
Tomcat с Apache
Еще одна вещь Если вы используете коннектор Apache + Tomcat + mod_JK, вам также необходимо внести следующие изменения:
- Добавьте URIEncoding = "UTF-8" в файл tomcat server.xml для соединителя 8009, он используется соединителем mod_JK.
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
- Гото ваш апач папку т.е.
/etc/httpd/conf
и добавить AddDefaultCharset utf-8
в httpd.conf file
. Примечание. Сначала проверьте, существует он или нет. Если существует, вы можете обновить его с помощью этой строки. Вы также можете добавить эту строку внизу.