如何从Velocity模板访问对象的公共字段

这是我的对象类:

public class Address { public final String line1; public final String town; public final String postcode; public Address(final String line1, final String town, final String postcode) { this.line1 = line1; this.town = town; this.postcode = postcode; } } 

我将它添加到速度上下文中,如下所示:

 Address theAddress = new Address("123 Fake St", "Springfield", "SP123"); context.put("TheAddress", theAddress); 

但是,在编写模板时,以下内容不会呈现地址字段(但是,当我将getter添加到Address类时它可以正常工作)

 
${TheAddress.line1} ${TheAddress.town} ${TheAddress.postcode}

是否可以在不添加getter的情况下访问Velocity上的对象的公共字段?

不是默认的。 您需要配置不同的Uberspect实现。

Velocity用户指南表明这是不可能的。 引用:

[Velocity]根据几个已建立的命名约定尝试不同的替代方案。 确切的查找顺序取决于属性名称是否以大写字母开头。 对于小写名称,例如$ customer.address,序列为

  1. 的getAddress()
  2. 的getAddress()
  3. 获得(“地址”)
  4. isAddress()

对于像$ customer.Address这样的大写属性名称,它略有不同:

  1. 的getAddress()
  2. 的getAddress()
  3. 获得(“地址”)
  4. isAddress()

http://wiki.apache.org/velocity/VelocityFAQ

问:如何在模板中访问对象的公共字段?

答:目前,您有三种选择:

  • 使用FieldMethodizer包装您的对象

  • 配置VelocityEngine以使用自定义uberspector,如PublicFieldUberspect

  • 如果没有找到匹配的方法,请将velocity-dev列表添加为将公共字段内省添加为默认回退:)

FieldMethodizer仅适用于公共静态字段。

PublicFieldUberspect示例代码很老,只是在不存在的字段上失败并出现错误。

忘记开发列表中的大厅。 )


同时, UberspectPublicFields在当前速度主干中有很好的缓存实现 。 不幸的是, 多年来没有积极的发展,也没有发布下一个版本的计划。 人们必须自己构建它并捆绑在私有存储库中。


另一个更改是具有额外scala兼容性的分支,可在中央maven存储库中找到: http : //maven-repository.com/artifact/com.sksamuel.scalocity/scalocity/0.9 。

降低而不是通常的速度依赖性:

  com.sksamuel.scalocity scalocity 0.9  

然后只需添加到velocity.properties

 runtime.introspector.uberspect = org.apache.velocity.util.introspection.UberspectPublicFields, org.apache.velocity.util.introspection.UberspectImpl 

需要注意的是, UberspectImpl补充了对scala属性的额外支持,需要8 MB scala jar。


最后,我只是将以下类从速度主干到实际项目:

org.apache.velocity.runtime.parser.node.PublicFieldExecutor org.apache.velocity.runtime.parser.node.SetPublicFieldExecutor org.apache.velocity.util.introspection.ClassFieldMap org.apache.velocity.util.introspection.Introspector org。 apache.velocity.util.introspection.IntrospectorBase org.apache.velocity.util.introspection.IntrospectorCache org.apache.velocity.util.introspection.IntrospectorCacheImpl org.apache.velocity.util.introspection.UberspectPublicFields

这些与Velocity 1.7一起工作得很好。

我做

 import org.apache.velocity.util.introspection.UberspectImpl; import org.apache.velocity.util.introspection.UberspectPublicFields; .... properties.setProperty("runtime.introspector.uberspect", UberspectImpl.class.getName() + ", " + UberspectPublicFields.class.getName()); 

一切正常!

Interesting Posts