Как получить доступ к общедоступным полям объекта из шаблона 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);

Однако при написании шаблона следующее не будет отображать поля адреса (однако он отлично работает, когда я добавляю геттеры в класс Address)

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

Можно ли получить доступ к публичным полям объектов из Velocity без добавления геттеров?


person Alex Spurling    schedule 12.06.2013    source источник


Ответы (4)


Не по умолчанию. Вам нужно настроить другую реализацию Uberspect.

person Nathan Bubna    schedule 12.06.2013
comment
Не могли бы вы добавить какие-либо подробности, такие как ссылка на документацию о том, как это сделать или почему это необходимо? - person Alex Spurling; 12.06.2013
comment
Это необходимо, потому что Velocity не поддерживает общедоступные поля. Попробуйте это: maven-doccheck.sourceforge.net/samples/ShinobuDemo/apidocs/org/ - person Nathan Bubna; 12.06.2013
comment
Великолепно, что они реализуют свою структуру в соответствии с соглашением, а не с реальными правилами языка... - person evanmcdonnal; 07.04.2016

В руководстве пользователя Velocity говорится, что это невозможно. Цитировать:

[Velocity] пробует различные альтернативы, основанные на нескольких установленных соглашениях об именах. Точная последовательность поиска зависит от того, начинается ли имя свойства с прописной буквы. Для имен в нижнем регистре, таких как $customer.address, последовательность следующая:

  1. получитьадрес()
  2. получитьадрес()
  3. получить("адрес")
  4. isAddress()

Для имен свойств в верхнем регистре, таких как $customer.Address, это немного отличается:

  1. получитьадрес()
  2. получитьадрес()
  3. получить("Адрес")
  4. isAddress()
person wau    schedule 12.06.2013

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

В: Как я могу получить доступ к общедоступным полям моего объекта в моих шаблонах?

О: В настоящее время у вас есть три варианта:

  • Оберните объект с помощью FieldMethodizer.

  • Настройте VelocityEngine для использования пользовательского уберспектра, такого как PublicFieldUberspect.

  • Пролоббируйте список разработчиков скорости, чтобы добавить интроспекцию в общедоступном поле в качестве запасного варианта по умолчанию, если не найден подходящий метод :)

FieldMethodizer работает только с общедоступными статическими полями.

Код примера PublicFieldUberspect довольно старый и просто не работает с ошибкой в ​​несуществующих полях.

И забудьте о лобби в списке разработчиков. )


Между тем, есть хорошее кэширование реализация UberspectPublicFields в текущем скоростном стволе. К сожалению, не было активной разработки в течение многих лет и не было планов на следующий выпуск опубликован. Нужно было бы собрать его самому и связать в частном репозитории.


Другой альтернативой является форк с дополнительной совместимостью со scala, который доступен в центральном репозитории maven: http://maven-repository.com/artifact/com.sksamuel.scalocity/scalocity/0.9.

Вставляем вместо обычной зависимости от скорости:

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

Затем просто добавьте к velocity.properties:

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

Предостережение заключается в том, что UberspectImpl исправлено с дополнительной поддержкой свойств scala и требует 8 МБ 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.

person Vadzim    schedule 03.07.2015

i do

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());

И все работает ОК!!!

person Евгений Колпако&    schedule 18.08.2018