Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать неотразимый комплимент Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?

Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Русские буквы в 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 - здесь расписано, как именно.

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

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

public void doPost(HttpServletRequest request,HttpServletResponse response)



throws ServletException, IOException

{

// Кодировка сообщений, использованная engine

// Некоторые используют ISO-8859-1, некоторые кодировку

// по умолчанию - единообразия тут нет

String requestEnc = "ISO-8859-1";

// Кодировка, установленная в броузере

String clientEnc = request.getParameter("charset");

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

// Получение параметра

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

//

if( value!=null )

value = new String(value.getBytes(requestEnc),clientEnc);

...

 

JSP

Технология JSP (Java Server Pages) очень похожа на сервлеты. По сути дела сервер, при запросе в первый раз на лету генерит из jsp-страниц код сервлета, компилирует его и запускает его как обычный сервлет. Поэтому у JSP возникают схожие проблемы при работе с русскими буквами. Однако решаются они немного по другому. Есть три места где могут возникнуть трудности - русские буквы внутри самой jsp-страницы, в ответе клиенту и в запросе от клиента. Первые два решаются заданием в начале страницы тега page:

<%@page contentType="text/html;charset=Windows-1251" %>

Увидев эту директиву сервер понимает, что страница записана в указанной кодировке, и что в сгенерённый код надо добавить вызов response.setContentType() с указанным contentType. Если сервер поддерживает спецификацию Servlet 2.3, то он также добавит и вызов request.setCharacterEncoding() с нужной кодировкой, таким образом автоматом решая и третью проблему. Для более старых серверов для раскодирования параметров в запросе клиента надо применять ухищрения, аналогичные описанным в разделе по сервлетам.

Для примера, для того, чтобы настроить JSP-форум Jive для работы с русскими буквами надо откорректировать следующие файлы:

/jive/header.jsp

/jive/admin/header.jsp

В них надо в начало добавить строчку

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

Вместо UTF-8 можно использовать любую кодировку, поддерживающую русские буквы - всё зависит от вкусов и предпочтений. Информацию об этом прислал Алексей Епишкин, за что ему отдельное спасибо.

В некоторых серверах встречаются баги, связанные с русскими буквами в JSP. Например, сервер Orion не любит русскую букву "Т" - он вместо неё в сгенерённый сервлет подставляет символ кавычки. Там во внутренностях есть примерно такой код:

...

switch( charstring.c1(i) )

...

public final char c1(int i)

{

if(i < 0 || i >= length)

throw new StringIndexOutOfBoundsException(i);

else

return (char)(data[offset + i] & 0xff);

data - это массив типа char[]. Как видно, ошибка тут тривиальна - разработчик почему-то был уверен что символы с кодами больше 255 - это ошибка природы. :-)






Date: 2015-10-18; view: 213; Нарушение авторских прав

mydocx.ru - 2015-2019 year. (0.008 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию