Имена Freemarker «.vars» не могут содержать тире?

#freemarker

#freemarker

Вопрос:

Мы используем Freemarker версии 2.3.16, и я только что обнаружил странную ошибку в одном из наших приложений. Дело дошло до того, что в некоторых строках кода нашего продукта теперь есть дефисы. Коды используются для извлечения хэшей локализованного текста из глобальной области видимости с помощью .vars .

Устранение проблемы привело меня к примеру, который может попробовать любой:

  • ${.vars["foo-bar"]} в шаблоне выводятся 0

  • ${.vars["foo bar"]} выводит nullnull

  • ${.vars["foobar"]} корректно вызывает исключение InvalidReferenceException

Все три должны вызывать исключения. Вместо этого, похоже, что вычисляется .vars строка параметра! 🙁

http://freemarker.sourceforge.net/docs/app_faq.html#faq_strange_variable_name подразумевает, что это должно сработать.

Я видел упоминание о подобной проблеме несколько недель назад в списке рассылки Freemarker, и было предложено добавить к строке параметра префикс «@». Это может работать с другими хэшами, но не работает с .vars . Я только что взял рабочий пример ( .vars["resources_title"] ) и, изменив его, вызвал исключение InvalidReferenceException ( .vars["@resources_title"] ). Я также попробовал это для ссылки через дефис, и это также вызвало исключение.

Обновление до 2.3.18, похоже, ничего не изменило.

Ответ №1:

Извините за задержку. После хорошей справки из списка рассылки о том, где ставить точки останова, вот что я написал в ответ на список от 10 июня:


Краткая история: Это не проблема Freemarker. Скорее команда Struts решила жестко настроить Freemarker для обработки .vars имен как выражений OGNL, и, похоже, нет способа сказать OGNL, чтобы они не разбирали их. Таким образом, в .vars именах под Struts не могут отображаться «-» и » » (и, возможно, другие символы).

Долгая история…

  • freemarker.core.BuiltinVariable В строке 192 Freemarker начинает обрабатывать .vars выражения

  • freemarker.core.Environment (строка 1088) передает управление «rootDataModel», экземпляром которого запрограммирована команда Struts org.apache.struts2.views.freemarker.ScopesHashModel

  • строка 70 этого класса (с использованием версии 2.1.8.1 Struts) вызывает «stack.findValue»; «stack» был подключен, чтобы быть экземпляром com.opensymphony.xwork2.ognl.OgnlValueStack

  • в строке 236 этот класс, в свою очередь, запрашивает экземпляр OgnlUtil для поиска объекта, и именно там предполагается, что имя является выражением OGNL и анализируется, превращая «foo-bar» в ( foo — bar)

Похоже, что ни на одном этапе пути нет возможности НЕ рассматривать .vars имя как выражение (комментарий в FreemarkerResult намекает на такую возможность, но код не выполняется). Теоретически я мог бы заставить свою реализацию FreemarkerManager создать вариант ScopesHashModel , но для этого потребовалось бы много работы, чтобы изменить все связанные с ней классы.

(Похоже, также не существует способа избежать символов «-» в выражениях OGNL. Кажется, 5-6 лет назад обсуждалось, как это сделать, но …. .vars( "foo\-bar" ) не удается найти «-» после «», так что, по-видимому, «-» невозможно избежать?)

🙁

Я не совсем понимаю, каков вариант использования для обработки .vars имен как выражений… но я не думаю, что Struts теперь изменится. Вместо того, чтобы переопределять полдюжины классов Struts, я вместо этого изменил код, который загружает наши пакеты ресурсов в стек значений: теперь он изменяет имена на замену «-» и «_», и аналогично мои .vars имена изменены таким же образом в шаблоне и … тада. Это работает. Вау.

Ответ №2:

У меня работает. И, как уже упоминалось в списке рассылки freemarker-user: может быть, вы используете странную модель данных или даже причудливую ObjectWrapper . Но подобное обсуждение, вероятно, лучше подходит для списка рассылки freemarker-user…

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

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

2. Хорошо, я прослежу за этим и там.

Ответ №3:

Это работает, если оно добавлено с помощью escape foo -bar. «Только одна обратная косая черта»

Ответ №4:

Начиная с версии 2.3.22 freemarker, возможно ли использовать точку (.), знак минуса (-) или двоеточие (:) в имени переменной (подробности здесь).

В моем случае это не удается, если я попытался использовать с переменными freemarker 2.3.21, такими как :

 api["x-link"]
  

Если я изменю freemarker на версию 2.3.22, это сработает.

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

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