How to access the public fields of an object from a Velocity template

Here is my feature class:

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; } } 

I add it to the speed context as follows:

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

However, when writing a template, the next field will not display the address fields (however, it works fine when I add getters to the Address class)

 <Address> <Line1>${TheAddress.line1}</Line1> <Town>${TheAddress.town}</Town> <Postcode>${TheAddress.postcode}</Postcode> </Address> 

Is it possible to access public object fields from Velocity without adding getters?

+7
source share
3 answers

Not by default. You need to set up another Uberspect implementation.

+4
source

Velocity User Guide assumes this is not possible. Quote:

[Velocity] tests various alternatives based on several established naming conventions. The exact search sequence depends on whether the property name begins with an uppercase letter. For lower case names, for example $ customer.address, the sequence

  • GetAddress ()
  • GetAddress ()
  • receive ("address")
  • isAddress ()

For uppercase property names such as $ customer.Address, it is slightly different:

  • GetAddress ()
  • GetAddress ()
  • receive ("Address")
  • isAddress ()
+3
source

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

Q: How can I access my public object fields in my templates?

A: You currently have three options:

  • Wrap your object with FieldMethodizer

  • Configure your VelocityEngine to use a custom uberspector such as PublicFieldUberspect

  • Lobby the-dev speed list to add self-analysis of the open field as the default backup if no suitable method is found :)

FieldMethodizer only works with public static fields.

PublicFieldUberspect sample code is pretty old, and it just fails with an error in non-existent fields.

And forget about the lobby on the developer list. )


Meanwhile, there is a good caching implementation of UberspectPublicFields in the current high-speed trunk . Unfortunately, there has been no active development for many years , and no plans for the next release are published. One of them would have to build it himself and link it in a private repository.


Another alternative is the scala bonus compatible plug, available in the central maven repository: http://maven-repository.com/artifact/com.sksamuel.scalocity/scalocity/0.9 .

Inclusion instead of the usual speed dependence:

 <dependency> <groupId>com.sksamuel.scalocity</groupId> <artifactId>scalocity</artifactId> <version>0.9</version> </dependency> 

Then just add to velocity.properties :

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

The UberspectImpl that UberspectImpl fixed with additional support for scala properties and requires an 8 MB scala jar.


In the end, I simply interned the following classes from the speed trunk into my own project:

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. apache.velocity.util.introspection.IntrospectorBase org.apache.velocity.util.introspection.IntrospectorCache org.apache.velocity.util.introspection.IntrospectorCacheImpl org.apache.velocity.util.introspection.UberspectPublicFields

They work great with Velocity 1.7.

0
source

All Articles