Курсовая работа: Java: Русские буквы и не только…
Но даже настроив JDBC-драйвер на нужную кодировку в некоторых случаях можно нарваться на неприятности. Например, при попытке использования новых замечательных скролируемых курсоров стандарта JDBC 2 в мосте JDBC-ODBC из JDK 1.3.x довольно быстро можно обнаружить, что русские буквы там просто не работают (метод updateString()).
С этой ошибкой связанна небольшая история. Когда я впервые её обнаружил (под JDK 1.3 rc2), я зарегистрил её на BugParade (4335564). Когда вышла первая бета JDK 1.3.1, эту ошибку пометили как пофиксеную. Обрадованный, я скачал эту бету, запустил тест - не работает. Написал Sun-овцам об этом - в ответ мне написали, что фикс будет включён в последующие релизы. Ну ладно, подумал я, подождём. Время шло, вышел релиз 1.3.1, а потом и бета 1.4. Наконец я нашёл время проверить - опять не работает. Мать, мать, мать... - привычно откликнулось эхо. После гневного письма в Sun они завели новую ошибку (4486195), которую отдали на растерзание индийскому филиалу. Индусы пошаманили над кодом, и заявили, что в 1.4 beta3 всё исправлено. Скачал я эту версию, запустил под ним тестовый пример, вот результат - 4546083. Как оказалось, та beta3, которую раздают на сайте (build 84) это не та beta3, куда был включён окончательный фикс (build 87). Теперь обещают, что исправление войдёт в 1.4 rc1... Ну, в общем, Вы понимаете :-)
Русские буквы в исходниках Java-программ
Как уже упоминалось, при выполнении программы используется Unicode. Исходные же файлы пишутся в обычных редакторах. Я пользуюсь Far-ом, у Вас, наверняка есть свой любимый редактор. Эти редакторы сохраняют файлы в 8-битовом формате, а значит, что к этим файлам также применимы рассуждения, аналогичные приведённым выше. Разные версии компиляторов немного по разному выполняют преобразование символов. В ранних версиях JDK 1.1.x используется настройка file.encoding, которую можно поменять при помощи нестандартной опции -J. В более новых (как сообщил Денис Кокарев - начиная с 1.1.4) был введён дополнительный параметр -encoding, при помощи которого можно указать используемую кодировку. В скомпилированных классах строки представлены в виде Unicode (точнее в модифицированном варианте формата UTF8), так что самое интересное происходит при компиляции. Поэтому, самое главное - выяснить, в какой кодировке у Вас исходники и указать правильное значение при компиляции. По умолчанию будет использован всё тот же пресловутый file.encoding. Пример вызова компилятора:
javac -encoding=KOI8_R ...
Кроме использования этой настройки есть ещё один метод - указывать буквы в формате "\uXXXX", где указывается код символа. Этот метод работает со всеми версиями, а для получения этих кодов можно использовать стандартную утилиту native2ascii.
Если Вы пользуетесь каким-либо IDE, то у него могут быть свои глюки. Зачастую эти IDE пользуются для чтения/сохранения исходников кодировку по умолчанию - так что обращайте внимание на региональные настройки своей ОС. Кроме этого могут быть и явные ошибки - например довольно неплохая IDE-шка CodeGuide плохо переваривает заглавную русскую букву "Т". Встроенный анализатор кода принимает эту букву за двойную кавычку, что приводит к тому, что корректный код воспринимается как ошибочный. Бороться с этим можно (заменой буквы "Т" на её код "\u0422"), но неприятно. Судя по всему где-то внутри парсера применяется явное преобразование символов в байты (типа: byte b = (byte)c), поэтому вместо кода 0x0422 (код буквы "Т") получается код 0x22 (код двойной кавычки).
Другая проблема встречается у JBuilder, но она больше связанна с эргономикой. Дело в том, что в JDK 1.3.0, под которым по умолчанию работает JBuilder, имеется бага (4312168), из-за которой вновь создаваемые окна GUI при активизации автоматически включают раскладку клавиатуры в зависимости от региональных настроек ОС. Т.е. если у Вас русские региональные настройки, то он будет постоянно пытаться переключиться на русскую раскладку, что при написании программ жутко мешается. На сайте JBuilder.ru есть парочка патчиков которые меняют текущую локаль в JVM на Locale.US, но самый лучший способ - перейти на JDK 1.3.1, в котором данная бага пофиксена.
Начинающие пользователи JBuilder могут также встретиться с такой проблемой - русские буквы сохраняются в виде кодов "\uXXXX". Чтобы этого избежать, надо в диалоге Default Project Properties, закладка General, в поле Encoding поменять Default на Cp1251.
Если Вы используете для компиляции не стандартный javac, а другой компилятор - обратите внимание на то, как он выполняет преобразование символов. Например, некоторые версии IBM-овского компилятора jikes не понимают, что бывают кодировки, отличные от ISO-8859-1 :-). Существуют версии, пропатченые на этот счёт, но часто там тоже зашивается некоторая кодировка - нет такого удобства, как в javac.
JavaDoc
Для генерации HTML-документации по исходникам используется утилита javadoc, входящая в стандартную поставку JDK. Для указания кодировок у неё есть аж 3 параметра:
-encoding - эта настройка задаёт кодировку исходников. По умолчанию используется file.encoding.
-docencoding - эта настройка задаёт кодировку генерируемых HTML-файлов. По умолчанию используется file.encoding.
-charset - эта настройка задаёт кодировку, которая будет записываться в заголовки генерируемых HTML-файлов (<meta http-equiv="Content-Type" content="text/html; charset=...">). Очевидно, что она должна совпадать с предыдущей настройкой. Если данная настройка опущена, то тег meta добавляться не будет.
Русские буквы в файлах properties
Для чтения файлов properties используются методы загрузки ресурсов, которые работают специфичным образом. Собственно для чтения используется метод Properties.load, который не использует file.encoding (там в исходниках жёстко указана кодировка ISO-8859-1), поэтому единственный способ указать русские буквы - использовать формат "\uXXXX" и утилиту native2ascii.
Метод Properties.save работает по разному в версиях JDK 1.1 и 1.2. В версиях 1.1 он просто отбрасывал старший байт, поэтому правильно работал только с англицкими буквами. В 1.2 делается обратное преобразование в "\uXXXX", так что он работает зеркально к методу load.
Если файлы properties у Вас загружаются не как ресурсы, а как обычные файлы конфигурации, и Вас не устраивает такое поведение - выход один, написать собственный загрузчик.
Русские буквы в Servlet-ах.
Ну, для чего эти самые Servlet-ы нужны, я думаю, Вы в курсе. Если нет - то лучше сначала прочитать документацию. Здесь же рассказывается только об особенностях работы с русскими буквами.
Так в чём же особенности? Когда Servlet посылает ответ клиенту, есть два способа послать этот ответ - через OutputStream (метод getOutputStream()) или через PrintWriter (метод getWriter()). В первом случае Вы записываете массивы байтов, поэтому применимы вышеописанные методы записи в потоки. В случае же PrintWriter, он использует установленную кодировку. В любом случае необходимо правильно указать используемую кодировку при вызове метода setContentType(), для того, чтобы было правильное преобразование символов на стороне сервера. Это указание должно быть сделано перед вызовом getWriter() или перед первой записью в OutputStream. Пример:
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException
{
// Установка кодировки ответа
// Учтите, что некоторые engine не допускают
// наличие пробела между ';' и 'charset'
response.setContentType("text/html;charset=Windows-1251");
PrintWriter out = response.getWriter();
// Отладочный вывод названия кодировки для проверки
out.println( "Encoding: " + response.getCharacterEncoding() );
...