Java: Русские буквы и не только…

Если кодировка указана не была, то по умолчанию предполагается кодировка UTF-8. На XML-парсер возложена обязанность корректно прочитать заголовок и использовать

Java: Русские буквы и не только…

Курсовой проект

Компьютеры, программирование

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

Компьютеры, программирование

Сдать работу со 100% гаранией
ил Денис Кокарев - начиная с 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() );

...

out.close();

}

Это по поводу отдачи ответов клиенту. Со входными параметрами, к сожалению не так просто. Входные параметры кодируются броузером побайтно в соответствии с MIME-типом "application/x-www-form-urlencoded". Как рассказал Алексей Менделев русские буквы броузеры кодируют, используя текущую установленную кодировку. Ну и, разумеется, ничего о ней не сообщают. Соответственно, например, в JSDK версий от 2.0 до 2.2 это никак не проверяется, а то, что за кодировка будет использована для преобразования - зависит от используемого engine. Начиная со спецификации 2.3 появилась возможность устанавливать кодировку для javax.servlet.ServletRequest - метод setCharacterEncoding(). Эту спецификацию уже поддерживают последние версии Resin и Tomcat.

Таким образом, если Вам повезло, и у Вас стоит сервер с поддержкой Servlet 2.3, то всё довольно просто:

public void doPost(HttpServletRequest request,HttpServletResponse response)

throws ServletException, IOException

{

// Кодировка сообщений

request.setCharacterEncoding("Cp1251");

String value = request.getParameter("value");

...

В применении метода request.setCharacterEncoding() есть одна существенная тонкость - он должен быть применен до первого обращения к запросу за данными (например request.getParameter()). Если Вы используете фильтры, которые обрабатывают запрос до того как он приходит в сервлет, есть ненулевая вероятность того, что в одном из фильтров может произойти чтение какого-нибудь параметра из запроса (например для авторизации) и request.setCharacterEncoding() в сервлете не сработает.

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

Пример такого фильтра:

import java.io.*;

import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class CharsetFilter implements Filter

{

// кодировка

private String encoding;

public void init(FilterConfig config) throws ServletException

{

// читаем из конфигурации

encoding = config.getInitParameter("requestEncoding");

// если не установлена - устанавливаем Cp1251

if( encoding==null ) encoding="Cp1251";

}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain next)

throws IOException, ServletException

{

request.setCharacterEncoding(encoding);

next.doFilter(request, response);

}

public void destroy(){}

}

И его конфигурации в web.xml:

<!--CharsetFilter start-->

<filter>

<filter-name>Charset Filter</filter-name>

<filter-class>CharsetFilter</filter-class>

<init-param>

<param-name>requestEncoding</param-name>

<param-value>Cp1251</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>Charset Filter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<!--CharsetFilter end-->

Если же Вам не повезло, и у Вас более старая версия - для достижения результата придётся поизвращаться:

Оригинальный способ работы с кодировками предлагает Russian Apache - здесь расписано, как именно.

Своё решение проблемы так же предложил Вячеслав Педак.

Ну а самый простейший вариант извлечь таки символы - передавать в комплекте пара

Похожие работы

<< < 1 2 3 4 5 6 7 8 > >>