Freemarker: доступ к публичному полю без использования метода получения в шаблоне - PullRequest
1 голос
/ 18 июня 2019

Я настраиваю представления в приложении Dropwizard и столкнулся с любопытной проблемой с Freemarker.

Следуя документам здесь Я настроил очень простой пример следующим образом

public class ExampleFreemarkerView extends View {
  private Foo foo;

  public ContractHtmlView(Foo Foo) {
    super("FooView.ftl");
    this.foo = foo;
  }

  public Contract getFoo() { return foo };
}

public class Foo {
  public String bar = "Hello World";
}

С FooView.ftl

<html>
  <body>
    <h1>${foo.bar}</h1>
  </body>
</html>

Ожидаемый вывод при рендеринге ExampleFreemarkerView - это HTML-документ, отображающий Hello World.

На самом деле Freemarker выдает исключение,с жалобой на то, что ${foo.bar}, в частности bar, не определено.

Похоже, это связано с тем, что bar является открытым полем без метода получения.Когда я добавляю public String getBar() { return bar; } getter к Foo, он работает.

Я несколько удивлен, что это так - то есть, что Freemarker, похоже, требует геттеры и не будет работать с открытыми полями изкоробка.Я намеренно использую открытые поля вместо геттеров / сеттеров в моих объектах модели, поэтому добавление геттеров просто для того, чтобы заставить Freemarker работать, не является решением, которое я рассмотрю.

Я много гуглил и читалчерез документы Freemarker, и просто не могу найти способ «включить» это поведение во Freemarker. Возможно ли это?

Просто для интереса - я тоже попробовал приведенный выше пример, точно такой же, но с шаблоном Усы и общедоступными полями там отлично (т.е. {{foo.bar}} рендеринг Hello World без вопросов).Это решает насущную проблему, так что этот вопрос в основном просто из любопытства, или в случае, если я решу использовать Freemarker вместо Усов по другим причинам.


Редактировать на основе комментариев - Я понимаю, что Freemarker делает это (настаивает на получении геттеров), чтобы следовать спецификации Java Beans, но большинство библиотек в экосистеме Java поддерживают открытые поля - Hibernate и Jackson являются яркими примерами - в той степени, в которой я лично рассматриваю это какодинаково действующий стандарт и найти библиотеки, не поддерживающие его, удивительно.

Ответы [ 2 ]

2 голосов
/ 22 июня 2019

Все зависит от настройки конфигурации objectWrapper.DefaultObjectWrapper (и любой подкласс BeansWrapper), который используется большинством проектов, имеет настройку exposeFields, которую можно установить на true.

В Dropwizard, что можно сделать следующим образом:Конфигурация YML, если вы настроили ViewBundle совместимым образом (на основе https://github.com/apache/freemarker-online-tester):

viewRendererConfiguration:
  freemarker:  # was `.ftl:` before Dropwizard 1.3.0
    objectWrapper=DefaultObjectWrapper(2.3.28, exposeFields=true)
1 голос
/ 18 июня 2019

Это указано в документах freemarker

Каждый объект будет помещен в TemplateHashModel, который будет предоставлять свойства и методы JavaBeans объекта.Таким образом, вы можете использовать model.foo в шаблоне для вызова методов obj.getFoo () или obj.isFoo ().(Обратите внимание, что открытые поля не видны напрямую; вы должны написать для них метод получения .)

Обратите внимание, что оно также следует концепция инкапсуляции Java

Также вы можете использовать framework как lombok getters , автоматически используя только аннотацию класса

...