当前位置: 首页 > 知识库问答 >
问题:

Freemarker:在模板中不使用getter访问公共字段

公冶谦
2023-03-14

我在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>

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

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

这似乎是因为bar是一个公共字段,没有getter。当我添加一个公共字符串getBar(){返回栏;}getter到Foo时,它就工作了。

我有点惊讶于这种情况——即Freemarker似乎需要getter,并且不能在开箱即用的情况下处理公共字段。我故意在模型对象上使用公共字段而不是吸气剂/设置器,所以添加GETTER只是为了让FrimaLARK工作不是我要考虑的解决方案。

我已经谷歌了很多,通读了Freemarker的文档,只是找不到任何方法在Freemarker中“开启”这种行为。有可能吗?

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

根据评论编辑-我知道Freemarker这样做(坚持让getters开箱即用)是为了遵循JavaBeans规范,但是Java生态系统中的大多数库都支持公共领域——Hibernate和Jackson是突出的例子——在某种程度上,我个人认为它是一个同样有效的标准,并且发现库不支持它,这令人惊讶。

共有2个答案

邹弘
2023-03-14

这在Freemarker文档里写着

每个对象都将被包装到一个TemplateHashModel中,该模型将公开对象的JavaBeans属性和方法。这样,您就可以使用模型。foo在模板中调用obj。getFoo()或obj。isFoo()方法。(请注意,公共字段不直接可见;必须为它们编写getter方法。)

注意,它也遵循java封装概念

此外,您还可以仅使用类注释自动将框架用作lombok getter

班承德
2023-03-14

这一切都取决于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)
 类似资料:
  • 问题内容: 这是我的对象类: 我将其添加到速度上下文中,如下所示: 但是,在编写模板时,以下内容将不会呈现地址字段(但是,当我将getter添加到Address类时,它可以正常工作) 是否可以通过Velocity访问对象上的公共字段而无需添加吸气剂? 问题答案: 默认不是。您需要配置其他Uberspect实现。

  • 我正在使用Smoks库进行XML到XML的转换。下面是Smoks配置。在freemarker模板中,我希望访问jdk库类以及我在项目中创建的类。请让我知道我如何实现这一点。

  • 是否可以访问模板中的设置变量? 设置: 如何使用,而不在模板中重用,以避免重复的代码,尤其是在其层次结构较深的情况下?

  • 使用Freemarker模板有两种不同的要求。一个是打印网页的某些部分,另一个是生成定制的HTML文件。我已将所有FTL文件放在路径WEB-INF/FTL/下,WEB应用程序从上述位置提取正确的FTL文件并打印网页。当我不得不生成HTML文件时,Freemarker无法找到相应的FTL文件。 我试图将特定的FTL文件保存在resources/FTL/下,但它仍然无法获取该文件。我在src下创建了一

  • 我有以下XML。 我想访问Freemarker模板中的“code”属性。下面是我的freemarker模板。 我尝试了以下模板。但他们都没有工作。 和

  • 我有一个Java类(我不能编辑,因为它是由Thrift自动生成的)定义如下: 但是,如果我尝试从静态编程语言获取,则不可用,并会产生未解决的引用错误。尝试使用字段会产生以下错误: 错误:(470,30)静态编程语言:重载解决歧义: 公共最终var消息:字符串!定义在com.example.TheirExctive 公共打开val消息:字符串?定义在com.example.TheirExctive