Почему аргументы Spring MessageSource неверно заполнены в некоторых локализациях?

#spring #internationalization #arguments #double-quotes

#spring #интернационализация #аргументы #двойные кавычки

Вопрос:

 mailconfirm.mail.body=<html><body><h3 style="margin: 0 0 1em;">Hi, {0}!</h3>
    To confirm your email address click on the confirmation link given bellow. If clicking on the link doesn't work, copy and paste the link in a new browser tab. <br /><br />
    <a href="http://www.domain.com/confirm_email.html?action=activateamp;hash={1}">http://www.domain.com/confirm_email.html?action=activateamp;hash={1}</a><br /><br />
    Kind regards,<br />
    Your Something
    </body></html>
  

Приведенное выше конкретное сообщение используется для приведенного ниже кода.

 String country = "AU";
Object[] args = new Object[] { account.getLogin(), confirm.getHash() };

helper.setText(appContext.getMessage("mailconfirm.mail.body", args,
                new Locale(country)), true);
  

Я отладил оба аргумента, и они оба имеют правильные значения. При отладке appContext.getMessage строки я увидел, что {1} параметр не заполнен правильным значением, однако {0} есть.

Есть идеи, что может быть не так? Я подозреваю, что это может быть какая-то проблема с локализацией.

Ответ №1:

Проблема решена! Похоже, проблема заключалась в том, что сообщение mailconfirm.mail.body содержало апостроф где-то после {0} и между {1}. После замены на doesn't на does not это устранило проблему. Я не знал, что там нельзя использовать апострофы. P.S. Это ошибка или просто моя ошибка, и апострофов следует избегать?

 mailconfirm.mail.body=<html><body><h3 style="margin: 0 0 1em;">Hi, {0}!</h3>
    To confirm your email address, click on the confirmation link given bellow. If clicking on the link doesn't work, copy and paste the link in a new browser tab. <br /><br />
    <a href="http://www.domain.com/confirm_email.html?action=activateamp;hash={1}">http://www.domain.com/confirm_email.html?action=activateamp;hash={1}</a><br /><br />
    Kind regards,<br />
    Your Something
    </body></html>
  

Один из них doesn't занял у меня около часа, чтобы разобраться с этим и протолкнуть исправление. Хахаха.. Отныне я считаю, что апострофирование — это зло!

Комментарии:

1. Ура! Поскольку вы потратили на это час, мне не пришлось. Кроме того, оказывается, что вы можете заставить свои одинарные кавычки работать должным образом, удвоив их, например '' . Это будет отображаться в виде одинарной кавычки, и это также будет хорошо сочетаться с аргументами MessageSource. Но, что сбивает с толку, это работает только в строках свойств, у которых есть параметры, в противном случае это приведет к отображению обоих апострофов.

2. Эта ссылка может быть полезна, чтобы лучше понять, что происходит: blog.pfa-labs.com/2010/07 /…

3. то же самое для mscharhag.com/2013/10 /… и флаг ResourceBundleMessageSource ‘s alwaysUseMessageFormat

4. примечание: если вы собираетесь скопировать / вставить приведенный выше mailconfirm.mail.body ….. обязательно измените doesn’t -> не выполняет…. По иронии судьбы, я потратил 30 минут на устранение этой проблемы, хаха.

5. Сэкономило мне часы и больше часов на исследованиях и с треском провалилось… Спасибо!!!!

Ответ №2:

Spring ResourceBundleMessageSource (который, я думаю, вы используете) использует MessageFormat для замены заполнителей ( {0} ) внутри сообщений. MessageFormat требуется, чтобы одинарные кавычки ( ' ) экранировались с использованием двух одинарных кавычек ( '' ) (см.: MessageFormat Javadoc).

Однако по умолчанию сообщения, которые не содержат никаких аргументов, не будут проанализированы MessageFormat . Таким образом, одинарные кавычки в сообщениях без аргументов не нужно экранировать.

ResourceBundleMessageSource предоставляет флаг с именем, alwaysUseMessageFormat который можно использовать, если MessageFormat его следует применить ко всем сообщениям. Таким образом, одинарная кавычка всегда должна быть экранирована двумя одинарными кавычками.

Смотрите это сообщение в блоге для получения более подробной информации.

Ответ №3:

Я не могу убедить свою бизнес-команду добавить двойные apos в необходимых местах, и иногда они также забывают. Итак, я просто переопределил ReloadableResourceBundleMessageSource#loadProperties как: если значение содержит, "'" amp; "{0" , то замените "'" на "''" и введите в свойства тот же ключ.

Комментарии:

1. Да, важно добавить double ‘ , ‘ в ваши messages.properties. Example: user.locked = Votre compte a u00E9tu00E9 bloquu00E9 parce que vous avez saisis {0} fois de suite un mauvais mot de passe. Ce blocage s»effectue pendant {1} minutes.

Ответ №4:

Альтернативой является использование String.format , изменение {X} на %s .

 mailconfirm.mail.body=<html><body><h3 style="margin: 0 0 1em;">Hi, %s!</h3>
    To confirm your email address click on the confirmation link given bellow. If clicking on the link doesn't work, copy and paste the link in a new browser tab. <br /><br />
    <a href="http://www.domain/confirm_email.html?action=activateamp;hash=%s">http://www.domain/confirm_email.html?action=activateamp;hash=%s</a><br /><br />
    Kind regards,<br />
    Your Something
    </body></html>


String whatEver = messageSource.getMessage("mailconfirm.mail.body", null, locale);

whatEver = String.format(whatEver,account.getLogin(), confirm.getHash() );
  

Надеюсь, это полезно.