Как да получите достъп до публичните полета на обект от шаблон 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>
    <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. getaddress()
  2. getAddress()
  3. get("адрес")
  4. isAddress()

За имена на свойства с главни букви като $customer.Address е малко по-различно:

  1. getAddress()
  2. getaddress()
  3. get("Адрес")
  4. isAddress()
person wau    schedule 12.06.2013

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.

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

<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 MB scala jar.


В крайна сметка току-що интернирах следните класове от velocity trunk в собствен проект:

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