Java
d8671b56

Русские буквы в Servlet-ах.


Ну, для чего эти самые Servlet-ы нужны, я думаю, Вы в курсе. Если нет - то лучше сначала прочитать документацию. Здесь же рассказывается только об особенностях работы с русскими буквами.

Так в чём же особенности? Когда Servlet посылает ответ клиенту, есть два способа послать этот ответ - через OutputStream (getOutputStream()) или через PrintWriter (getWriter()). В первом случае Вы записываете массивы байтов, поэтому применимы вышеописанные методы записи в файл. В случае же PrintWriter, он использует установленную кодировку. В любом случае необходимо правильно указать используемую кодировку при вызове метода setContentType(), для того, чтобы было правильное преобразование символов на стороне сервера. Это указание должно быть сделано перед вызовом getWriter() или перед первой записью в OutputStream. Пример:

public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { 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.1 это никак не проверяется. Собственно для раскодирования используются методы HttpUtils.parsePostData() и HttpUtils.parseQueryString(), которые просто обнуляют старший байт. Это зарегистрированная ошибка в JSDK (). К сожалению, эту ошибку закрыли как "Will not be fixed", с тем оправданием, что, дескать, раз в RFC на эту тему ничего не сказанно, то и делать мы ничего не будем. Однако, после переписки наших разработчиков в майл-листе дело, похоже, сдвинулось с мёртвой точки. По крайней мере на словах было обещано включить метод установки кодировки в спецификацию JSDK 2.3.

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

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

Ну а самый простейший вариант извлечь таки символы - передавать в комплекте параметров имя кодировки (или, если вы уверены в текущей кодировке броузера, использовать предопределённую кодировку) и использовать метод перекодировки символов:

public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { // Кодировка сообщений // В связке MSIE 4.01 SP1 -> JSDK 2.0 servletrunner.exe всегда выдаёт "ISO-8859-1" String requestEnc = request.getCharacterEncoding(); // Некоторые servlet engine, не мудрствуя лукаво, возвращают null if( requestEnc==null ) requestEnc="ISO-8859-1"; String clientEnc = request.getParameter("charset"); if( clientEnc==null ) clientEnc="Cp1251"; String value = new String(request.getParameter("value").getBytes(requestEnc),clientEnc);

работает. :-)

В общем, опыт в написании Servlet-ов у меня небольшой, так что Ваши замечания будут приветствоваться.



Содержание раздела