我正在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
是一个公共领域,没有吸气剂。当我向public String getBar() { return bar; }
添加Foo
吸气剂时,它会起作用。
我确实对这种情况感到有些惊讶-也就是说,Freemarker似乎需要使用吸气剂,并且无法直接使用公共领域。我故意在模型对象上使用公共字段,而不是使用getter / setter,因此,我不考虑添加getter来使Freemarker正常工作。
我在Google上搜索了很多内容,并阅读了Freemarker文档,但找不到任何方法可以在Freemarker中“打开”此行为。 有可能吗?
仅出于兴趣-我也尝试了上面的示例,但完全相同,但是使用Mustache模板和公共字段可以正常工作(即{{foo.bar}}
呈现Hello World
没问题)。这就解决了眼前的问题,所以这个问题主要是出于好奇,或者万一我出于其他原因决定使用Freemarker替代Mustache。
基于评论进行编辑-我了解Freemarker这样做(坚持使用吸气剂)是为了遵循Java Beans规范,但是Java生态系统中的大多数库都支持公共字段- Hibernate和Jackson是杰出的例子-就我个人而言,它是同等有效的标准,并且发现不支持它的库令人惊讶。
答案 0 :(得分:2)
这全部取决于objectWrapper
的配置设置。大多数项目正在使用的DefaultObjectWrapper
(以及任何BeansWrapper
子类)具有exposeFields
设置,可以将其设置为true
。
在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)
答案 1 :(得分:1)
每个对象都将被包装到一个TemplateHashModel中,该模板将公开该对象的JavaBeans属性和方法。这样,您可以在模板中使用model.foo来调用obj.getFoo()或obj.isFoo()方法。 (请注意,公共字段不是直接可见的;您必须为它们编写一个getter方法。)
请注意,它也遵循java encapsulation concept
您还可以仅使用类注释自动将框架用作lombok getters