我在Dropwizard应用程序中设置视图,并在Freemarker中遇到了一个奇怪的问题。

docs here之后,我建立了一个非常简单的示例,如下所示

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时的预期输出是显示Hello World的HTML文档。

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

这似乎是因为bar是一个公共字段,没有getter。当我将public String getBar() { return bar; }吸气剂添加到Foo时,它可以工作。

对于这种情况,我感到有些惊讶-即Freemarker似乎需要使用吸气剂,并且无法直接使用公共领域。我故意在模型对象上使用公共字段,而不是使用getter / setter,因此,我不会考虑添加getter只是为了使Freemarker正常工作。

我在Google上搜索了很多东西,并阅读了Freemarker文档,但找不到任何方法可以在Freemarker中“打开”此行为。可能吗?

只是出于兴趣-我也尝试了上面的示例,完全相同,但是使用Mustache模板和公共字段可以很好地工作(即{{foo.bar}}呈现Hello World没有问题)。这就解决了眼前的问题,所以这个问题主要是出于好奇,或者万一出于其他原因我决定在胡子上使用Freemarker。



根据评论进行编辑-我了解Freemarker这样做(坚持使用吸气剂)以遵循Java Beans规范,但是在我个人看来,Java生态系统中的大多数库都支持公共领域-Hibernate和Jackson是突出的示例它是同样有效的标准,并且发现不支持它的库令人惊讶。

最佳答案

这完全取决于objectWrapper配置设置。大多数项目使用的DefaultObjectWrapper(以及任何BeansWrapper子类)具有可以设置为exposeFieldstrue设置。

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

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

09-10 08:36
查看更多