Как получить UTF-8 работает в Java webapps?



мне нужно, чтобы UTF-8 работал в моем Java webapp (сервлеты + JSP, не используется фреймворк) для поддержки äöå etc. для обычного финского текста и кириллических алфавитов, таких как ЦжФ для особых случаев.



Мои настройки следующие:




  • среда разработки: Windows XP

  • производственная среда: Debian


используемая база данных: MySQL 5.x



пользователи в основном используют Firefox2, но и Opera 9.x, FF3, IE7 и Google Chrome являются используется для доступа к сайту.



как этого добиться?

807   13  

13 ответов:

отвечая себе, как FAQ этого сайта поощряет его. Это работает для меня:

в основном символы äåö не являются проблемой, поскольку набор символов по умолчанию, используемый браузерами и tomcat / java для webapps, является latin1 ie. ISO-8859-1, который "понимает" эти символы.

чтобы заставить UTF-8 работать под Java + Tomcat + Linux/Windows+Mysql требуется следующее:

настройка сервера Tomcat.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=*ж*

символ ж обрабатывается как 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.

другой дело сделано с помощью этого фильтра, чтобы установить кодировку ответа по умолчанию ie. кодировка, в которой возвращается 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 wiki (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-meta теги

кодировка страницы 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-соединение

при использовании БД, необходимо определить, что соединение использует кодировку UTF-8. Это делается в контексте.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&amp;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 путем изменения мой.ini -файл и в Linux по настройке мой.cnf -файл. В этих файлах должно быть определено, что все клиенты, подключенные к серверу, используют 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.xml, которые получают параметры запроса кодируются в 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 it кодирует этот символ правильно как %D0%B6.

если и когда браузеры проинструктированы читать страницы в кодировке UTF-8 (с заголовками запросов и метатегом html), по крайней мере Firefox 2/3 и другие браузеры с этого периода все кодируют символ как %D0%B6.

конечным результатом является то, что все пользователи с именем "Petteri" найдены, а также все пользователи с именем "ж" найдены.

а как же ААА?

HTTP-спецификация определяет, что по умолчанию URL-адреса кодируются как latin1. Это приводит к в firefox2, firefox3 etc. кодирование следующего

    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

результат из этого следует, что веб-приложение совершенно не может корректно обрабатывать параметры запроса из запросов GET, поскольку некоторые символы кодируются в latin1, а другие в 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 тип столбца или использовать utf8 набор символов (что требует MySQL 5.5.3 или более поздней версии). Просто имейте в виду, что с помощью utf8 набор символов в MySQL не будет работать 100% времени.

Tomcat с Apache

еще одна вещь, если вы используете Apache + Tomcat + mod_JK разъем, то вам также нужно сделать следующие изменения:

  1. добавить URIEncoding= "UTF-8" в сервер tomcat.xml-файл для соединителя 8009, он используется соединителем mod_JK. <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
  2. перейти к вашей папке apache т. е. /etc/httpd/conf и добавить AddDefaultCharset utf-8 на httpd.conf file. Примечание: сначала проверить, что он существует или нет. Если существует, вы можете обновить его с помощью этой строки. Вы также можете добавить эту строку внизу.

Я думаю, что вы довольно хорошо подытожили это в своем собственном ответе.

в процессе UTF-8-ing(?) из конца в конец вы также можете убедиться, что сама java использует UTF-8. Использовать Единственный Способ Иметь Установленный.encoding=utf-8 в качестве параметра для JVM (может быть настроен в catalina.летучая мышь.)

добавить kosoant это, если вы используете Spring, а не пишете свой собственный фильтр сервлетов, вы можете использовать класс org.springframework.web.filter.CharacterEncodingFilter они предоставляют, настраивая его следующим образом в вашем интернете.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>

Это для греческого кодирования в таблицах MySql, когда мы хотим получить к ним доступ с помощью Java:

используйте следующую настройку соединения в пуле соединений 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>

Если вы не хотите помещать это в пул соединений JNDI, вы можете настроить его как JDBC-url, как показано в следующей строке:

jdbc:mysql://192.168.10.123:3308/mydatabase?characterEncoding=greek

для меня и Ника, так что мы никогда не забудем его и тратить время больше.....

хороший подробный ответ. просто хотел добавить еще одну вещь, которая определенно поможет другим увидеть кодировку UTF-8 на URL-адресах в действии .

выполните следующие действия, чтобы включить кодировку UTF-8 на URL-адресах в firefox.

  1. введите "about: config" в адресной строке.

  2. используйте тип входного фильтра для поиска " сеть.стандартный URL-адрес.свойство encode-query-utf8.

  3. выше свойство будет иметь значение false по умолчанию, поверните это к истине.
  4. перезапустить браузер.

кодировка UTF-8 на URL работает по умолчанию в IE6 / 7 / 8 и chrome.

хочу также добавить от здесь эта часть решила мою проблему utf:

runtime.encoding=<encoding>

Я с аналогичной проблемой, но, в именах файлов файла я сжимаю с Apache commons. Итак, я решил это с помощью следующей команды:

convmv --notest -f cp1252 -t utf8 * -r

это работает очень хорошо для меня. Надеюсь, это поможет кому-нибудь;)

для моего случая отображения символа Юникода из пакетов сообщений мне не нужно применять раздел "кодировка страницы JSP" для отображения Юникода на моей странице jsp. Все, что мне нужно, это раздел "CharsetFilter".

еще один момент, который не был упомянут, относится к Сервлетам Java, работающим с Ajax. У меня есть ситуации, когда веб-страница собирает текст utf-8 от пользователя, отправляющего его в файл JavaScript, который включает его в URI, отправленный сервлету. Сервлет запрашивает базу данных, захватывает результат и возвращает его в виде XML в файл JavaScript, который форматирует его и вставляет отформатированный ответ в исходную веб-страницу.

в одном веб-приложении я следил за ранней книгой Ajax инструкции по завершению JavaScript при построении URI. Пример в книге использовал метод escape (), который я обнаружил (трудный путь) неверен. Для utf-8 необходимо использовать encodeURIComponent ().

в наши дни мало кто бросает свой собственный Ajax, но я подумал, что могу также добавить это.

о CharsetFilter упоминается в ответе @ kosoant ....

есть в Filter в tomcat web.xml (расположенном в conf/web.xml). Фильтр называется setCharacterEncodingFilter и комментируется по умолчанию. Вы можете раскомментировать это ( пожалуйста, не забудьте раскомментировать его filter-mapping тоже )

также нет необходимости набор jsp-config в своем web.xml (у меня есть тест для Tomcat 7+)

некоторое время вы можете решить проблему с помощью мастера администратора MySQL. В

переменные запуска > дополнительно>

и установить Def. набор символов: utf8

возможно, эта конфигурация нуждается в перезапуске MySQL.

предыдущие ответы не работали с моей проблемой. Это было только в производстве, с tomcat и apache mod_proxy_ajp. Пост тела потеряли не ASCII-символов путем ? Проблема, наконец, была с JVM defaultCharset (US-ASCII в установке по умолчанию: Charset dfset = Charset.defaultCharset();) Итак, решение было запущено Tomcat server с модификатором для запуска JVM с UTF-8 в качестве кодировки по умолчанию:

JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8" 

(добавить эту строку catalina.sh и сервис tomcat restart)

может быть, вы также необходимо изменить системную переменную linux (edit ~/.и bashrc и ~/.профиль для постоянного изменения, см. https://perlgeek.de/en/article/set-up-a-clean-utf8-environment)

экспорт LC_ALL=en_US.UTF-8
экспорт LANG=en_US.UTF-8

язык экспорта=en_US.UTF-8

в случае, если вы указали в пуле соединений (mysql-ds.xml), в вашем Java-коде вы можете открыть соединение следующим образом:

DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Connection conn = DriverManager.getConnection(
    "jdbc:mysql://192.168.1.12:3308/mydb?characterEncoding=greek",
    "Myuser", "mypass");

Comments

    Ничего не найдено.