Кодировка JSP UTF

Мне трудно понять, как справиться с этой проблемой:

Я разрабатываю веб-инструмент для итальянского университета, и мне нужно отображать слова с ударением (например, è, ù, ...); иногда я получаю эти слова из таблицы PostgreSql (в кодировке UTF8), но в основном мне приходится читать длинные отрывки из файла. Эти файлы кодируются в формате utf-8 xml и прекрасно отображаются в Smultron или любом редакторе utf-8 (они были созданы при разборе старых файлов python с такими объектами, как è вместо "è").

Я написал класс Java, который извлекает соответствующие сегменты из файла XML, который работает следующим образом:

String s = parseText(filename, position)

если я записываю возвращенную строку в файл, все выглядит хорошо; проблема в том, что если я сделаю

out.write(s)

на странице JSP я получаю странные символы. Кстати, я использую

String s = getWordFromPostgresql(...)

out.write(s)

в том же JSP, и он показывает ОК.

Любой намек?

Спасибо Никола


@ krosenvold

Спасибо за ваш ответ, однако эта директива уже есть на странице, но она не работает (на самом деле она "работает", но только для строк, которые я получаю из базы данных). Я думаю, что есть что-то о чтении из файлов, но я не могу понять... они работают в "Java", но не в "JSP" (не могу придумать лучшего объяснения...)

Вот базовый пример, извлеченный из фактического кода: метод для чтения из файлов возвращает Map, от Mark (объекта, представляющего позицию в тексте) до String (содержащего текст):

это на странице.jsp (с указанием utf-директивы в постах выше)

    // ...
    Map<Mark, String> map = TestoMarkParser.parseMarks(...);
    out.write(map.get(m));

и вот результат:

"Fu però così in uso il Genere Enharmonico, che quelli quali vi si esercitavano",

если я помещу тот же код в Java-класс и заменим out.write на System.out.println, результат будет следующим:

"Fu però così in uso il Genere Enharmonico, che quelli quali vi si esercitavano",


Я провел некоторый анализ с помощью шестнадцатеричного редактора, вот он:

оригинальная строка: "fu però così "

в XML-файле: C3 B2

в соответствии с out.write() в файле JSP: E2 88 9A E2 89 A4

как записано в файл через:

FileWriter w = new FileWriter(new File("out.txt"));
w.write(s);     // s is the parsed string
w.close();

C3 B2

печать значений каждого символа в виде целого

0: 70 = F
1: 117 = u
2: 32 =  
3: 112 = p
4: 101 = e
5: 114 = r
6: 8730 = � 
7: 8804 = � 
8: 32 =  
9: 99 = c
10: 111 = o
11: 115 = s
12: 8730 = �
13: 168 = �
14: 10 = `

4 ответа

В директиве jsp page вы должны попытаться установить тип контента на utf-8, что также установит pageEncoding на utf-8.

<%@page contentType="text/html;charset=UTF-8"%>

UTF-8 не является типом контента по умолчанию в jsp, и из этого возникают всевозможные интересные проблемы. Проблема заключается в том, что основной поток по умолчанию интерпретируется как поток ISO-8859-1. Если вы запишите некоторые байты Юникода в этот поток, они будут интерпретированы как ISO-8859-1. Я считаю, что установка кодировки в utf-8 является лучшим решением.

Изменить: Кроме того, строковая переменная в Java всегда должен быть Unicode. Так что вы всегда должны быть в состоянии сказать

System.out.println(myString) 

и увидеть правильный набор символов, приходящий в окне консоли вашего веб-сервера (или просто зайти в отладчик и проверить его). Я подозреваю, что вы будете видеть неправильные символы, когда будете делать это, что заставляет меня думать, что у вас есть проблема с кодированием при построении строки.

У меня есть несколько международных jsp [которые имеют "специальные" международные (относительно английского) символы].

Вставка этого [и только этого, то есть: также никакой директивы contentType (которая сделала дублирующую ошибку contentType)] в верхней части их заставила их сохранить и правильно отобразить:

<%@page pageEncoding="UTF-8"%>

Эта ссылка [http://www.inter-locale.com/codeset1.jsp] помогла мне обнаружить это.

У меня тоже была такая же проблема, все "utf-8" и почему я вижу
бессмысленные символы и проблема была в jsp и она должна быть во главе страницы.

 <%request.setCharacterEncoding("utf-8");%>

и все будет хорошо.

String s = parseText(filename, position)

Где этот метод определен? Я предполагаю, что это ваш собственный метод, который открывает файл и извлекает определенный фрагмент данных. Где-то в этом процессе он преобразуется из байтов в символы, возможно, используя кодировку по умолчанию для вашей JVM.

Если кодировка по умолчанию вашей работающей JVM не соответствует фактической кодировке в файле, вы получите неправильные символы в вашей строке. Кроме того, если вы читаете контент, который закодирован в многобайтовой форме (такой как UTF-8), ваша "позиция" может указывать на середину многобайтовой кодировки.

Если исходные файлы находятся в правильно сформированном XML, вам будет гораздо лучше использовать реальный синтаксический анализатор (например, встроенный в JDK) для их синтаксического анализа, поскольку синтаксический анализатор обеспечит правильный перевод байтов в символы. Затем используйте выражение XPath для получения значений.

Если вы не использовали анализатор XML в прошлом, вот два документа, которые я написал о разборе и XPath.


Редактировать: одна вещь, которую вы можете найти полезной, это распечатать фактические значения символов в строке, используя что-то вроде следующего:

public static void main(String[] argv) throws Exception
{
    String s = "testing\u20ac";
    for (int ii = 0 ; ii < s.length() ; ii++)
    {
        System.out.println(ii + ": " + (int)s.charAt(ii) + " = " + s.charAt(ii));
    }
}

Вам, вероятно, следует также распечатать ваш набор символов по умолчанию, чтобы вы знали, как любая конкретная последовательность байтов переводится в символы:

public static void main(String[] argv) throws Exception
{
    System.out.println(Charset.defaultCharset());
}

И, наконец, вы должны проверить обслуживаемую страницу как необработанные байты, чтобы точно узнать, что возвращается клиенту.


Правка № 2: символ "Unicode" имеет значение 00F2, которое будет в кодировке UTF-8 как C3 B2. Эти два кода не соответствуют символам, которые вы указали в предыдущем ответе.

Дополнительные сведения о символах Unicode см. В таблицах кодов на Unicode.org.

Другие вопросы по тегам