Jak uruchomić UTF-8 W Java webapps?
Muszę uruchomić UTF-8 w mojej Java webapp (servlets + JSP, nie używany framework) do obsługi äöå
itp. dla zwykłego fińskiego tekstu i alfabetów cyrylicy, takich jak ЦжФ
dla szczególnych przypadków.
Moja konfiguracja jest następująca:
- środowisko programistyczne: Windows XP
- środowisko produkcyjne: Debian
Używana baza danych: MySQL 5.x
Użytkownicy używają głównie Firefox2, ale także opery 9.x, FF3, IE7 i Google Chrome są używane do uzyskania dostępu do witryny.
Jak osiągnąć to?
13 answers
odpowiadając sobie jako FAQ tej strony zachęca do tego. To działa dla mnie:
Większość znaków nie jest problematyczna, ponieważ domyślnym zestawem znaków używanym przez przeglądarki i tomcat / java dla webapps jest latin1 ie. ISO-8859-1, który "rozumie" te znaki.
Aby UTF-8 działał pod Javą + Tomcat+Linux / Windows+Mysql wymaga:
Konfigurowanie serwera Tomcat.xml
Konieczne jest skonfigurowanie, aby złącze używało UTF - 8 to encode url (GET request) parameters:
<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"
/>
Kluczowa część to URIEncoding= "UTF-8" W powyższym przykładzie. To gwarantuje, że Tomcat obsługuje wszystkie przychodzące parametry GET jako kodowane UTF-8. W rezultacie, gdy użytkownik zapisuje na pasku adresu przeglądarki:
https://localhost:8443/ID/Users?action=search&name=*ж*
Znak ж jest obsługiwany jako UTF-8 i jest kodowany (zwykle przez przeglądarkę, zanim trafi na serwer) jako %d0%B6.
POST request are nie ma to wpływu.
CharsetFilter
Następnie nadszedł czas, aby zmusić Java webapp do obsługi wszystkich żądań i odpowiedzi jako UTF-8 zakodowane. Wymaga to zdefiniowania filtra zestawu znaków w następujący sposób:
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() {
}
}
Ten filtr upewnia się, że jeśli przeglądarka nie ustawiła kodowania użytego w żądaniu, to jest ustawiona na UTF-8.
Inną rzeczą wykonaną przez ten filtr jest ustawienie domyślnego kodowania odpowiedzi ie. kodowanie, w którym zwrócony html / whatever is. Alternatywą jest Ustawienie kodowania odpowiedzi itp. w każdym kontrolerze aplikacji.
Ten filtr musi być dodany do www.xml lub deskryptor wdrożenia aplikacji 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>
Instrukcje tworzenia tego filtra znajdują się na Tomcat wiki (http://wiki.apache.org/tomcat/Tomcat/UTF-8 )
Kodowanie stron JSP
W Twojej sieci.xml , dodaj "po": {]}
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
Alternatywnie, wszystkie strony JSP webapp musiałby mieć następujące na górze z nich:
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
Jeśli używany jest jakiś układ z różnymi fragmentami JSP, to jest to potrzebne w wszystkich z nich.
HTML - meta tagi
Kodowanie strony JSP mówi JVM, aby obsługiwał znaki na stronie JSP w prawidłowym kodowaniu. Następnie nadszedł czas, aby powiedzieć przeglądarce, w którym kodowaniu jest strona html:
To jest zrobione z poniższym u góry każdej strony XHTML wyprodukowanej przez 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
Podczas używania db, należy zdefiniować, że połączenie używa kodowania UTF-8. Odbywa się to w kontekście .xml lub gdziekolwiek połączenie JDBC jest defiend w następujący sposób:
<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"
/>
Baza danych MySQL i tabele
Używana baza danych musi używać kodowania UTF-8. Można to osiągnąć poprzez utworzenie bazy danych o następującej treści:
CREATE DATABASE `ID_development`
/*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;
Wtedy, wszystkie tabele muszą być również w 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;
Kluczowym elementem jest CHARSET = utf8.
Konfiguracja serwera MySQL
MySQL serveri również musi być skonfigurowany. Zazwyczaj odbywa się to w systemie Windows poprzez modyfikację my.ini - plik i w Linuksie konfigurując my.cnf - plik. W tych plikach powinno być zdefiniowane, że wszyscy klienci podłączeni do serwera używają utf8 jako domyślnego zestawu znaków i że domyślnym zestawem znaków używanym przez serwer jest również utf8.
[client]
port=3306
default-character-set=utf8
[mysql]
default-character-set=utf8
Procedury i funkcje Mysql
Te również muszą mieć zdefiniowany zestaw znaków. Na przykład:
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 requests: latin1 and UTF-8
Jeśli i kiedy jest zdefiniowany w serwerze tomcat.xml, w którym parametry żądania GET są kodowane w UTF-8, następujące żądania GET są obsługiwane poprawnie:
https://localhost:8443/ID/Users?action=search&name=Petteri
https://localhost:8443/ID/Users?action=search&name=ж
Ponieważ znaki ASCII są kodowane w ten sam sposób zarówno z latin1, jak i UTF-8, łańcuch" Petteri " jest obsługiwany prawidłowo.
Cyrylica ж nie jest w ogóle zrozumiana w języku łacińskim1. Ponieważ Tomcat jest poinstruowany, aby obsługiwać parametry żądania jako UTF-8, koduje ten znak poprawnie jako %D0 % B6.
Jeśli i kiedy przeglądarki są poinstruowane, aby czytać strony w kodowaniu UTF-8( z nagłówkami żądań i meta-tagiem html), przynajmniej Firefox 2/3 i inne przeglądarki z tego okresu same kodują znak jako %d0%B6.
Efektem końcowym jest to, że wszystkie znaleziono użytkowników o nazwie "Petteri", a także wszystkich użytkowników o nazwie "ж".
Ale co z äåö?
Http-Specyfikacja definiuje, że domyślnie adresy URL są kodowane jako latin1. Skutkuje to firefox2, firefox3 itp. kodowanie następującej
https://localhost:8443/ID/Users?action=search&name=*Päivi*
W wersji zakodowanej
https://localhost:8443/ID/Users?action=search&name=*P%E4ivi*
W języku latin1 znak ä jest zakodowany jako % E4. mimo że strona/request/everything jest zdefiniowana tak, aby używała UTF-8. Kodowanie UTF-8 wersja ä to %C3 % A4
Wynikiem tego jest to, że jest to zupełnie niemożliwe dla webapp do correly obsługi parametrów żądania z żądań GET, ponieważ niektóre znaki są zakodowane w latin1 i inne w UTF-8. Uwaga: żądania POST działają, ponieważ przeglądarki kodują wszystkie parametry żądania z formularzy całkowicie w UTF-8, jeśli strona jest zdefiniowana jako UTF-8
Rzeczy do przeczytania
Bardzo wielkie podziękowania dla autorów poniższych za udzielenie odpowiedzi na mój problem:
- 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 /
Ważna Uwaga
Mysql obsługuje podstawową płaszczyznę wielojęzyczną przy użyciu 3-bajtowych znaków UTF-8. Jeśli musisz wyjść poza to (niektóre alfabety wymagają więcej niż 3-bajtów UTF-8), Następnie należy użyć typu kolumny VARBINARY
lub użyć utf8mb4
zestaw znaków (który wymaga MySQL 5.5.3 lub nowszego). Pamiętaj tylko, że używanie zestawu znaków utf8
W MySQL nie będzie działać w 100%.
Tomcat z Apache
Jeszcze jedno jeśli używasz łącznika Apache + Tomcat + mod_JK, musisz również wprowadzić następujące zmiany:
- Dodaj URIEncoding = "UTF-8" do serwera tomcat.plik xml dla złącza 8009, jest to używany przez złącze mod_JK.
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
- Pobierz folder apache tj.
/etc/httpd/conf
i dodajAddDefaultCharset utf-8
whttpd.conf file
. Uwaga: najpierw sprawdź, czy istnieje, czy nie. Jeśli istnieje, możesz go zaktualizować za pomocą tej linii. Możesz dodać tę linię również na dole.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-11 16:07:44
Myślę, że całkiem dobrze to podsumowałeś we własnej odpowiedzi.
W procesie UTF-8-ing(?) od końca do końca możesz również chcieć upewnić się, że sama java używa UTF-8. Use-Dfile.encoding = utf-8 jako parametr do JVM (można skonfigurować w catalina.bat).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-27 21:54:08
Aby dodać do odpowiedź kosoanta , Jeśli używasz Springa, zamiast pisać własny filtr serwletów, możesz użyć klasy org.springframework.web.filter.CharacterEncodingFilter
, którą dostarczają, konfigurując ją w następujący sposób w Twojej sieci.xml:
<filter>
<filter-name>encoding-filter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>FALSE</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:13
To jest dla greckiego kodowania w tabelach MySql, gdy chcemy uzyskać do nich dostęp za pomocą Javy:
Użyj poniższej konfiguracji połączenia w puli połączeń JBoss (mysql-DS.xml)
<connection-url>jdbc:mysql://192.168.10.123:3308/mydatabase</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>nts</user-name>
<password>xaxaxa!</password>
<connection-property name="useUnicode">true</connection-property>
<connection-property name="characterEncoding">greek</connection-property>
Jeśli nie chcesz umieszczać tego w puli połączeń JNDI, możesz skonfigurować go jako JDBC-url, jak ilustruje następna linia:
jdbc:mysql://192.168.10.123:3308/mydatabase?characterEncoding=greek
Dla mnie i Nicka, żebyśmy nigdy o tym nie zapomnieli i nie tracili czasu.....Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-04 13:52:33
Ładna szczegółowa odpowiedź. chciałem tylko dodać jeszcze jedną rzecz, która na pewno pomoże innym zobaczyć kodowanie UTF-8 na adresach URL w akcji .
Wykonaj poniższe kroki, aby włączyć kodowanie UTF-8 na adresach URL w Firefoksie.
Wpisz "about:config" w pasku adresu.
Użyj typu wejścia filtra, aby wyszukać "sieć.standard-url.właściwość encode-query-utf8".
- powyższa właściwość będzie domyślnie false, zmień ją na TRUE.
- Uruchom ponownie przeglądarka.
Kodowanie UTF-8 na adresach URL działa domyślnie w IE6 / 7 / 8 i chrome.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-19 01:30:34
Chcę również dodać z Tutaj ta część rozwiązała mój problem utf:
runtime.encoding=<encoding>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-15 02:19:46
Mam podobny problem, ale w nazwach plików kompresuję za pomocą Apache commons. Więc rozwiązałem to poleceniem:
convmv --notest -f cp1252 -t utf8 * -r
Dla mnie działa bardzo dobrze. Mam nadzieję, że komuś pomoże;)Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-20 13:45:30
W moim przypadku wyświetlania znaków Unicode z pakietów wiadomości, nie muszę stosować sekcji "kodowanie stron JSP", aby wyświetlić Unicode na mojej stronie jsp. Potrzebuję tylko sekcji "CharsetFilter".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-21 01:59:03
Jeszcze jedna kwestia, o której nie wspomniano, dotyczy serwletów Javy pracujących z Ajaxem. Mam sytuacje, gdy strona internetowa odbiera tekst utf-8 od użytkownika wysyłającego go do pliku JavaScript, który zawiera go w URI wysłanym do Servletu. Servlet odpytuje bazę danych, przechwytuje wynik i zwraca go jako XML do pliku JavaScript, który go formatuje i wstawia sformatowaną odpowiedź do oryginalnej strony internetowej.
W jednej aplikacji internetowej śledziłem wczesną książkę Ajax instrukcje zawijania JavaScript podczas konstruowania URI. Przykład w książce zastosował metodę escape (), którą odkryłem (the hard way) jest błędny. Dla utf - 8 musisz użyć encodeuricomponent ().
Niewiele osób wydaje się w dzisiejszych czasach tworzyć własny Ajax, ale pomyślałem, że równie dobrze mogę to dodać.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-14 22:30:51
O CharsetFilter
wspomnianym w @kosoant odpowiedz ....
web.xml
(znajduje się w conf/web.xml
) znajduje się Wbudowany Moduł Filter
. Filtr ma nazwę setCharacterEncodingFilter
i jest domyślnie komentowany. Możesz to odkomentować (pamiętaj, aby również odkomentować jego filter-mapping
)
Nie ma też potrzeby ustawiania jsp-config
w twoim web.xml
(mam test na Tomcat 7+)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-09 05:24:48
Jakiś czas możesz rozwiązać problem za pomocą Kreatora administratora MySQL. In
Zmienne startowe > Zaawansowane >
I ustawić Def. char Set: utf8
Może ten config wymaga restartu MySQL.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-13 18:34:13
Poprzednie odpowiedzi nie zadziałały z moim problemem. Był tylko w produkcji, z tomcat i apache mod_proxy_ajp. Post body lost non ASCII chars by ? Problem w końcu pojawił się z JVM defaultCharset (US-ASCII w domyślnej instalacji: Charset Dfset = Charset.defaultCharset();) tak więc, rozwiązaniem było uruchomienie serwera tomcat z modyfikatorem, aby uruchomić JVM z UTF-8 jako domyślnym zestawem znaków:
JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"
(Dodaj ten wiersz do catalina.sh i service tomcat restart)
Może Ty też musisz się zmienić zmienna systemu linux (edycja ~/.bashrc i ~/.profil do trwałej zmiany, zobacz https://perlgeek.de/en/article/set-up-a-clean-utf8-environment )
Export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8Export LANGUAGE=en_US.UTF-8
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-17 06:18:01
W przypadku, gdy podałeś w puli połączeń (mysql-DS.xml), w kodzie Java można otworzyć połączenie w następujący sposób:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Connection conn = DriverManager.getConnection(
"jdbc:mysql://192.168.1.12:3308/mydb?characterEncoding=greek",
"Myuser", "mypass");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-09 12:42:41