Відповідаючи на себе як FAQ на цьому веб-сайті це заохочує. Це працює для мене:
Переважно символи äåö не є проблематичним, оскільки набір символів за замовчуванням, який використовується браузерами та tomcat / java для веб-сайтів, є latin1, тобто. ISO-8859-1, який "розуміє" цих символів.
Щоб UTF-8 працював під Java + Tomcat + Linux / Windows + Mysql, потрібно:
Налаштування сервера Tomcat.xml
Потрібно налаштувати, що роз'єм використовує UTF-8 для кодування параметрів URL-адреси (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"
/>
Ключова частина - URIEncoding = "UTF-8" у наведеному вище прикладі. Це гарантує, що Tomcat обробляє всі вхідні параметри GET як закодовані UTF-8. Як результат, коли користувач записує в адресний рядок браузера наступне:
https://localhost:8443/ID/Users?action=search&name=*ж*
символ ж обробляється як UTF-8 і кодується (як правило, браузером ще до того, як потрапити на сервер) як % D0% B6 .
На запит POST це не впливає.
CharsetFilter
Тоді саме час змусити java webapp обробляти всі запити та відповіді як закодовані 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>
Інструкції щодо створення цього фільтра можна знайти на wiki 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-сторінка:
Це робиться за допомогою наступного вгорі кожної сторінки xhtml, створеної веб-сайтом:
<?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-з'єднання
Під час використання db слід визначити, що для з'єднання використовується кодування 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 ;
Отримайте запити: latin1 та UTF-8
Якщо і коли в сервері tomcat's 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*
У latin1 символ ä кодується як % E4 . Навіть незважаючи на те, що сторінка / запит / все визначено для використання UTF-8 . Версія ä, закодована UTF-8, є % C3% A4
Результатом цього є те, що webapp цілком неможливо правильно обробити параметри запиту з 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% часу.
Томат з апачем
Ще одна річ Якщо ви використовуєте роз'єм 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
. Примітка. Спочатку перевірте, чи існує він чи ні. Якщо існує, ви можете оновити її за допомогою цього рядка. Ви також можете додати цей рядок і внизу.