Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Кодировка. Сервлет. Unix. Проблемма.


Автор: Lubomyr 3.10.2005, 14:50
Сервлет получает Post с формы (кирилицу) и перекодирует его непонятным образом.
То есть если выводить ето значение - получается непонятный набор непонятных символов. Под Windows все работает коректно!
При чем данные из базы, кирилица закодированная в сервлете выводятся коректно всегда.
Кодировка везде UTF-8;
Сервер JBOSS 3.2.1.
В самом начале всегда стоит request.setCharacterEncoding("UTF-8");
Когда надо выводить ставлю - response.setContentType("text/html; charset=UTF-8");
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" .... тоже везде;
Даже уже ACCEPTCHARSET="utf-8" везде в формах поставил...
Понимаю, что проблемма может быть в региональных настройках или настройках ОС (Free BSD).
Нельзя ли сделать код независимым от этих настроек?
И что вообще надо исправить?

Буду признателен за ответ.

Автор: tux 4.10.2005, 13:41
Цитата(Lubomyr @ 3.10.2005, 19:50)
В самом начале всегда стоит request.setCharacterEncoding("UTF-8");

Насколько я понимаю кодировка выставляется уже в сервлете. Попробуй выставлять ее в фильтре. Класс фильтра примерно такой:
Код

import java.io.*;
import javax.servlet.*;

public class SelectLanguageFilter implements Filter {
    private String encoding;
    
    public void init(FilterConfig config) throws ServletException {
        encoding = config.getInitParameter("requestEncoding");
        
        if(encoding==null) encoding="utf-8";
    }
    
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain next)
    throws IOException, ServletException {
        try {
            request.setCharacterEncoding(encoding);
            next.doFilter(request, response);
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }
    
    public void destroy(){}
}

В web.xml нужно добавить следующее:
Код

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

    ...

    <filter>
        <filter-name>SelectLanguageFilter</filter-name>
        <filter-class>SelectLanguageFilter</filter-class>
      <init-param>
        <param-name>requestEncoding</param-name>
        <param-value>utf-8</param-value>
      </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>SelectLanguageFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  
</web-app>

Автор: Lubomyr 10.10.2005, 15:45
Спасибо. Сделал так. Все равно данные которые получены методом Get request.getParameter считывает в кодировке ISP-8859-1, а приходят они в правильной, UTF-8.
То есть строку в пинципе можно получить, используя:

String newString = new String(badString.getBytes("ISO-8859-1"), "UTF-8");

Но это не универсальный подход... Под другой платформой может не сработать...
Post работает нормально.

Автор: seth 1.10.2006, 20:06
Прописал фильтр - а он выдает ошибку - не могу понять почему (используется struts)
Код

1/10/2006 19:56:03 org.apache.catalina.startup.HostConfig checkResources
INFO: Undeploying context [/gg]
org.apache.jasper.JasperException
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:370)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:291)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at SelectLanguageFilter.doFilter(SelectLanguageFilter.java:16)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
    at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
    at java.lang.Thread.run(Thread.java:595)

Автор: 3x3 1.10.2006, 23:43
Цитата(Lubomyr @ 10.10.2005,  15:45)
Спасибо. Сделал так. Все равно данные которые получены методом Get request.getParameter считывает в кодировке ISP-8859-1, а приходят они в правильной, UTF-8. 
То есть строку в пинципе можно получить, используя:

String newString  = new String(badString.getBytes("ISO-8859-1"), "UTF-8");

Но это не универсальный подход... Под другой платформой может не сработать...
Post работает нормально.

http://forum.vingrad.ru/index.php?showtopic=113274&st=30 читай.

Jsp должно начинаться заклинанием:
Код

<% if(request.getCharacterEncoding() == null) request.setCharacterEncoding("UTF-8"); %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


Не принудительным выставление кодировки, заметь, а только если она не выставлена.
С сервлетом так же: Для начала любой деятельности - настроить кодировку реквеста и респонса.

Это всё. 



Автор: UnicornMirage 2.10.2006, 08:48
Цитата

Понимаю, что проблемма может быть в региональных настройках или настройках ОС (Free BSD).
Нельзя ли сделать код независимым от этих настроек?


нужно запустить JBoss или какой там у тебя сервер - с параметром 
Код

-Dfile.encoding=windows-1251


и UTF не будет нужен

Автор: y3u 2.10.2006, 10:52
Цитата(UnicornMirage @  2.10.2006,  08:48 Найти цитируемый пост)
нужно запустить JBoss или какой там у тебя сервер - с параметром 

код Java
1:

-Dfile.encoding=windows-1251


ни фига подобного, во-первых - это параметр для дефолтной кодировки зачитываемых ридерами файлов, при чем тут реквест/респонз? во-вторых, при таком параметре я не смогу работать со, скажем, китайским, арабским, японским, ивритом и пр...
В JAVA надо юзать юникодные кодировки!

Автор: UnicornMirage 2.10.2006, 10:57
просто ты сказал что работаешь с кириллицей - зачем тогда юникод - лишняя трата трафика?

установка этого параметра не влияет на реквесты/респонсы - т.к. там они задаются как было сказано выше.
а вот этот параметр указывает виртуальной машине кодировку по-умолчанию, не зависимо от настроек ОС.
и поэтому если ты напишешь

Код

byte[] data = ...; // прочитанные откуда то из реквеста
String str = new String(data);


то у тебя данные в строке будут в той кодировке, которая была в 
-Dfile.encoding=windows-1251


а у автора темы было жестко привязано в коде:
Код

String newString = new String(badString.getBytes("ISO-8859-1"), "UTF-8");

Автор: ishi 3.10.2006, 23:49
Цитата(Lubomyr @ 3.10.2005,  14:50)
Нельзя ли сделать код независимым от этих настроек?
И что вообще надо исправить?

Здравствуйте! Наконец нашел время ответить. Значит, дело обстоит так:
0)Хватит флудить о том, чего не знаете, хотя в спорах рождается истина, но вы уже задолбали человека.

1).Дело в том, что платформа тут ни при чем. Фирме sun давно известно о проблемах с интернациональными кодировками в сервлетах. Они разработали специальный пакет National Servlets, Который решает эту проблему. Класс простенький и не требует переписания всего кода сервлета.
 2) Второй вопрос, это то , что tomcat довольно примитивно определяет кодировку запроса, поэтому не удивительно, что в большинстве случаев это null или ничего не значащий "url-encoding". Советую почитать, если для вас это важно, эту статью "http://ishi.dev.juga.ru/servlet/site?tar=gt&theme=106", причем обратите внимание, что сайт, на который вы зайдете сидит на линуксе, полностью построен на сервлетах + MySQL, так что это живой пример решения вашей проблемы.
3) Третий вопрос - это MySQL драйвер может корежить кодировки при получении из базы строковых данных. Здесь я тоже могу подкинуть один класс, который решает эту проблему. Но если Ваш сайт используется в коммерческих целях, то класс будет платный.

Автор: tux 4.10.2006, 02:12
Цитата(ishi @  4.10.2006,  04:49 Найти цитируемый пост)
1).Дело в том, что платформа тут ни при чем. Фирме sun давно известно о проблемах с интернациональными кодировками в сервлетах. Они разработали специальный пакет National Servlets, Который решает эту проблему. Класс простенький и не требует переписания всего кода сервлета.

National Servlets - это вот это - http://servlets.chat.ru/? О, великий гуру, простите за глупость, но при чем же здесь Sun? 

Цитата(ishi @  4.10.2006,  04:49 Найти цитируемый пост)
2) Второй вопрос, это то , что tomcat довольно примитивно определяет кодировку запроса, поэтому не удивительно, что в большинстве случаев это null или ничего не значащий "url-encoding". Советую почитать, если для вас это важно, эту статью "http://ishi.dev.juga.ru/servlet/site?tar=gt&theme=106", причем обратите внимание, что сайт, на который вы зайдете сидит на линуксе, полностью построен на сервлетах + MySQL, так что это живой пример решения вашей проблемы.

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

Цитата(ishi @  4.10.2006,  04:49 Найти цитируемый пост)
3) Третий вопрос - это MySQL драйвер может корежить кодировки при получении из базы строковых данных. Здесь я тоже могу подкинуть один класс, который решает эту проблему. Но если Ваш сайт используется в коммерческих целях, то класс будет платный. 

Пардон, еще раз извиняюсь. А где выше в теме было про MySQL? Оффтоп, однако. Кстати, насчет коммерции. Если вы будете руки использовать в коммерческих целях, могу предложить дрова по сходной цене.

Цитата(ishi @  4.10.2006,  04:49 Найти цитируемый пост)
0)Хватит флудить о том, чего не знаете, хотя в спорах рождается истина, но вы уже задолбали человека.

Знаете, здесь без вас есть кому решать где флуд, а где нет. Минус за неуважение к сообществу форума.

Автор: 3x3 4.10.2006, 02:40
Цитата(tux @ 4.10.2006,  02:12)

Цитата(ishi @  4.10.2006,  04:49 Найти цитируемый пост)
обратите внимание, что сайт, на который вы зайдете сидит на линуксе, полностью построен на сервлетах + MySQL, так что это живой пример решения вашей проблемы.

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

Приложение-то, насколько я понял, его. 

Автор: tux 4.10.2006, 02:45
Цитата(3x3 @  4.10.2006,  07:40 Найти цитируемый пост)
Приложение-то, насколько я понял, его.  

Думаю да. На juga.ru используется Resin, там кажется можно дефолтные кодировки request и response установить в настройках сервера, поэтому с русскими буквами проблем быть не должно. Хотя могу и ошибаться, надо глянуть.

Автор: 3x3 4.10.2006, 02:49
Цитата(tux @ 4.10.2006,  02:45)
Цитата(3x3 @  4.10.2006,  07:40 Найти цитируемый пост)
Приложение-то, насколько я понял, его.  

Думаю да. На juga.ru используется Resin, там кажется можно дефолтные кодировки request и response установить в настройках сервера, поэтому с русскими буквами проблем быть не должно. Хотя могу и ошибаться, надо глянуть.

Да, на нём: http://forum.juga.ru/showthread.php?threadid=295

____
По крайней мере своей рекламой он пропиарил хостинг smile

Автор: ishi 4.10.2006, 21:32
Да ребята, не пойму, к чему вообще тогда велась беседа. 
National Servlets - это пакет от sun? а не чат. Вы плохо искали . Я приложу его в файле. Во вторых на juga.ru сидит сайт - пример, в разработке которого я принимал участие. Это ishi.dev.juga.ru. что касается всяких там дефолтов, то этот сайт сделан как пример работы независимо от настроек. 
Что касается коммерции, то надо уважать чужой труд. И если мои друзья потрудились разработать класс, который позволяет работать на любом хосте незадумываясь о настройках, а кто то использует его, чтобы бабулетов заработать, то я сам приверженец того, чтобы делиться с теми, кто мне помогает. Так что имею полное право предупреждать о коммерческом использовании.
Касательно того как tomcat определяет кодировку запроса, то я смотрел в коде САМОГО и ничего примитивнее ещё не видел в этом смысле, будь это хоть трижды спецификация. Так что если человеку нужна помощь, я предложил действенный совет. Попробуйте и увидите.
..... А как файл присоединить. ... В общем не найду такой кнопки здесь. Если найду ссылку на sun-овском сайте, вернее вспомню, то пришлю. Хотя можете сами поискать.
И juga.ru  просто показал вам пример, как работает то , о чем я говорю. Вживую. Кстати, у них сегодня с сервером проблемы. Причам часто такое. Так что пиарить там нечего. Ну прчему вы болтаете как вам хочется, а мне так сразу минус. Может я так разговариваю.
Ладно, всем удачи. Надеюсь, чем то помог.

Автор: ishi 4.10.2006, 21:52
Цитата(3x3 @ 4.10.2006,  02:49)
Цитата(tux @ 4.10.2006,  02:45)
Цитата(3x3 @  4.10.2006,  07:40 Найти цитируемый пост)
Приложение-то, насколько я понял, его.  

Думаю да. На juga.ru используется Resin, там кажется можно дефолтные кодировки request и response установить в настройках сервера, поэтому с русскими буквами проблем быть не должно. Хотя могу и ошибаться, надо глянуть.

Да, на нём: http://forum.juga.ru/showthread.php?threadid=295

____
По крайней мере своей рекламой он пропиарил хостинг smile

Вы привели эту ссылку http://forum.juga.ru/showthread.php?threadid=295 по поводу Resin. Это что шутка такая?

У меня дома стоит FreeDSD 4 без русского языка вообще, без иксов. Только jdk1.4, jre 5, apache 3 с чем то и 5-й tomcat. на виртуальной машине работает, как отдельный компьютер. На tomcat сидит такой же мой сайт, как я вам приводил в примере. Так вот, я обращаюсь к нему из винды и с русскими буквами проблем тоже нет, хотя я там ничего вообще не настраивал дополнительно, лень просто. Всё по умолчанию.

Автор: y3u 4.10.2006, 22:25
Цитата(ishi @  4.10.2006,  21:32 Найти цитируемый пост)
National Servlets 

мне вот тоже стало интересно smile что-то не нашел я поиском на оффсайте жабы ничего про National Servlets... Гугель тоже ничего не сказал по этому поводу smile
ishi.dev.juga.ru - упал, там сломалсо сервлетег, точнее там тупо налл поинтер эксцепшон в древнем при древнем Oracle's XSQL Servlet  smile
Кстати, не понятно, каким образом я смогу получить информацию о том как там в примере все работает, не имея его исходников?

вобсчем, что-то вы темните, гражданин smile Код на трепанацию!

Автор: sandello 5.10.2006, 07:56
Коллега на работе написал кратенькую инструкцию для борьбы с кодировкой в томкате:
Код

При работе web-приложений может возникнуть проблема с кодировкой русских
символов, отправленных через GET-параметры. Для решения проблемы нужно
указать tomcat'у использовать кодировку UTF-8 при декодировании URI
принимаемых запросов. Для этого в файле server.xml в элементе <Connector>
HTTP-соединений нужно указать атрибут URIEncoding="UTF-8". Также рекомендуется
добавить фильтр для сервлета приложения, в котором принудительно выставлять
кодировку принимаемых HTTP-запросов в UTF-8.

Автор: 3x3 5.10.2006, 12:59
Цитата(sandello @ 5.10.2006,  07:56)
Коллега на работе написал кратенькую инструкцию для борьбы с кодировкой в томкате:
Код

...принудительно выставлять
кодировку принимаемых HTTP-запросов в UTF-8...



... если её Томкат не определил сам.

________

Во всех этих решения с юникодом, кстати, мне видится одна маленькая проблемка. Похоже борьба с кодировками на входе - это ерунда по сравнению с кодировками на выходе.

Вдруг придет такой HTTP-клиент, который тупо понимает только Windows-1251 и никаких юникодов не акцептит? Что будет в этом случае? Станет контейнер перекодировать UTF-8 своих сервлетов в кодировку клиента или будет тупо гнать ему юникод, четко зная, из Accept-chaset, что клиент этого не понимает?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)