Изменение локали приложения меняет всех пользователей (Vaadin)

В моем приложении я устанавливаю локаль, когда пользователь входит в систему, чтобы локализовать компоненты. Недавно я давал демо и заметил, что язык переключается с английского на голландский без видимой причины. Оказалось, что к демонстрационному серверу (размещенному на немецком сервере) в то же время обращался другой человек, который установил для него голландский язык, и это повлияло на мою английскую демонстрацию и наоборот.

Я попробовал это на своем компьютере с разными браузерами, используя обычный режим Chrome и режимы инкогнито и т. д., чтобы имитировать разные сеансы, и проблема присутствует. Любые идеи о том, как справиться/исправить это? Я думал, что Vaadin уже самостоятельно обрабатывает пользовательские сеансы, но кажется, что переменные приложения являются общими?

Вот что я делаю в своем приложении, чтобы изменить локаль:

@Override
    public void setLocale(Locale locale) {
        super.setLocale(locale);
        xerb = ResourceBundle.getBundle("com.bluecubs.xinco.messages.XincoMessages", getLocale());
}

Затем пакет ресурсов xerb используется для интернационализации пользовательского интерфейса. Я пытался не выполнять супервызов, но результат тот же, как если бы xerb модифицировался различными сеансами и распределялся между ними.

Любые идеи?

Тот же вопрос на форуме Vaadin: https://vaadin.com/forum/-/message_boards/view_message/1091312

Изменить

Используя шаблон ThreadLocal, я добавил выходные данные, когда каждый экземпляр получен, и я вижу разные экземпляры для каждого браузера. (например, com.bluecubs.xinco.core.server.vaadin.Xinco@2114ed для первого и com.bluecubs.xinco.core.server.vaadin.Xinco@fd68fe для второго браузера), поэтому я считаю, что модель используется правильно. . К сожалению, я все еще вижу ту же проблему.


person javydreamercsw    schedule 26.01.2012    source источник
comment
Что такое xerb? Это поле в классе, которое расширяет com.vaadin.Application?   -  person Artur Nowak    schedule 27.01.2012
comment
Просто ResourceBundle, используемый для интернационализации. Это не статическая переменная. Но да, поле в классе, которое расширяет com.vaadin.Application   -  person javydreamercsw    schedule 27.01.2012
comment
Так как же тогда вы получаете доступ к этому полю xerb из других классов? Используете ли вы шаблон ThreadLocal?   -  person Artur Nowak    schedule 27.01.2012
comment
xerb — это локальная переменная в приложении. У него есть общедоступный метод для доступа к нему: public ResourceBundle getResource(), но он вызывается из экземпляра приложения, отправленного в пользовательские компоненты, созданные из приложения (т.е. ссылающиеся на тот же контекст IMO)   -  person javydreamercsw    schedule 30.01.2012
comment
Глядя на шаблон ThreadLocal, точно не использую его.   -  person javydreamercsw    schedule 30.01.2012
comment
Артур, вы можете написать правильный ответ, используя шаблон ThreadLocal, чтобы начислить баллы? Хотя это оказалось в основном ошибкой кода, ключевой частью был указатель на шаблон ThreadLocal.   -  person javydreamercsw    schedule 01.02.2012
comment
Рад, что вы нашли ошибку! Конечно, я думаю, в первую очередь другим людям будет легче найти ответ, если они столкнутся с той же проблемой :)   -  person Artur Nowak    schedule 01.02.2012


Ответы (2)


Попробуйте применить шаблон ThreadLocal для доступа к экземпляру Application из других элементов управления в приложение. Таким образом, это становится более явным, когда вы пытаетесь получить некоторую информацию, относящуюся к сеансу. Это также довольно широко распространено в приложениях Vaadin, поэтому код может быть более читабельным.

Передача ссылки на поля вашего Application косвенно, сделав его внешним классом для анонимных слушателей, может привести к трудно обнаруживаемым ошибкам, потому что может быть трудно определить точный момент создания элементов управления и то, на что ResourceBundle ссылались в этот самый момент. точка.

person Artur Nowak    schedule 01.02.2012
comment
Помимо ошибки в моем коде, использование шаблона ThreadLocal было реальным ключом к решению этой проблемы. - person javydreamercsw; 02.02.2012
comment
есть хорошая реализация этого шаблона под лицензией apache code.google.com/p/dellroad-stuff/source/browse/trunk/src/java/ - person ilcavero; 16.02.2012

Vaadin обрабатывает пользовательские сеансы и хранит переменные отдельно, так что это ненормальное поведение. Поле «xerb» должно быть каким-то образом разделено между пользователями. Единственные несколько причин этого, о которых я могу думать прямо сейчас, это

  1. xerb — статическое поле
  2. ResourceBundle, на который указывает xerb, является тем же самым (статическим)
  3. Фактический экземпляр Application используется совместно пользователями.

Вы уже сказали, что № 1 не является причиной. № 2 может быть, но я не знаю, возможно ли это. Вариант 3 возможен, если у вас есть пользовательский ApplicationServlet, содержащий ошибку, из-за которой он возвращает один и тот же экземпляр Application для всех пользователей. Или, возможно, есть какой-то механизм внедрения, вводящий одно и то же во все приложения?

Без дополнительной информации невозможно узнать, что на самом деле происходит.

ХТН

person Jonatan    schedule 27.01.2012
comment
Я не совсем понимаю № 2. Для меня 1 и 2 одинаковы. Когда вы объявляете ResourceBundle, он ссылается на файл свойств, который нельзя изменить во время выполнения. Если Vaadin обрабатывает пользовательские сеансы, то нестатические переменные не должны совместно использоваться экземплярами. Пользовательский сервлет приложения отсутствует. Нет механизма впрыска (по крайней мере, представленного мной). Какую еще информацию вы хотели бы узнать? На всякий случай исходный код здесь: xinco.svn.sourceforge.net/svnroot/xinco /багажник - person javydreamercsw; 30.01.2012