Freemarker:在模板中没有 getter 的情况下访问公共字段

dav*_*wil 2 java freemarker public-members dropwizard dropwizard-templates

我正在 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";
}
Run Code Online (Sandbox Code Playgroud)

FooView.ftl

<html>
  <body>
    <h1>${foo.bar}</h1>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

呈现时的预期输出ExampleFreemarkerView是显示 的 HTML 文档Hello World

实际发生的是 Freemarker 抛出异常,抱怨${foo.bar}- 特别bar是 - 未定义。

这似乎是因为bar是一个公共字段,没有吸气剂。当我向 中添加public String getBar() { return bar; }getter 时Foo,它会起作用。

我对这种情况感到有些惊讶 - 即 Freemarker 似乎需要 getter 并且不能开箱即用地使用公共字段。我故意在我的模型对象上使用公共字段而不是 getter/setter,所以添加 getter 只是为了让 Freemarker 工作不是我会考虑的解决方案。

我在谷歌上搜索了很多并阅读了 Freemarker 文档,但找不到任何方法可以在 Freemarker 中“打开”这种行为。是否可以?

只是为了兴趣 - 我也尝试了上面的示例,完全相同,但是使用 Mustache 模板和公共字段在那里工作正常(即{{foo.bar}}渲染Hello World没有问题)。这解决了当前的问题,所以这个问题主要是出于好奇,或者我出于其他原因决定使用 Freemarker 而不是 Mustache。


根据评论进行编辑-我知道 Freemarker 这样做(坚持开箱即用的 getter)以遵循 Java Beans 规范,但 Java 生态系统中的大多数库都支持公共领域 - Hibernate 和 Jackson 是突出的例子 - 就我个人而言它作为一个同样有效的标准,发现不支持它的库令人惊讶。

dde*_*any 5

这一切都取决于objectWrapper配置设置。大多数项目正在使用的DefaultObjectWrapper(和任何子BeansWrapper类)都有一个exposeFields可以设置为true.

在 Dropwizard 中,如果您ViewBundle以兼容的方式(基于https://github.com/apache/freemarker-online-tester)进行设置,则可以在配置 YML 中这样做:

viewRendererConfiguration:
  freemarker:  # was `.ftl:` before Dropwizard 1.3.0
    objectWrapper=DefaultObjectWrapper(2.3.28, exposeFields=true)
Run Code Online (Sandbox Code Playgroud)