Configure velocity to render an object with someth

2019-08-08 22:34发布

问题:

Is there a way to configure Velocity to use something other than toString() to convert an object to a string in a template? For example, suppose I'm using a simple date class with a format() method, and I use the same format every time. If all of my velocity code looks like this:

$someDate.format('M-D-yyyy')

is there some configuration I could add that would let me just say

$someDate

instead? (Assuming I'm not in a position to just edit the date class and give it an appropriate toString()).

I'm doing this in the context of a webapp built with WebWork, if that helps.

回答1:

You could also create your own ReferenceInsertionEventHandler that watches for your dates and automatically does the formatting for you.



回答2:

Velocity allows for a JSTL like utility called velocimacros:

http://velocity.apache.org/engine/devel/user-guide.html#Velocimacros

This would allow you to define a macro like:

#macro( d $date)
   $date.format('M-D-yyyy')
#end

And then call it like so:

#d($someDate)


回答3:

Oh, and the 1.6+ versions of Velocity have a new Renderable interface. If you don't mind tying your date class to a Velocity API, then implement this interface and Velocity will use the render(context, writer) method (for your case, you just ignore the context and use the writer) instead of toString().



回答4:

I faced this problem too and I was able to solve it based on Nathan Bubna answer.

I'm just trying to complete the answer providing the link to Velocity documentation which explains how to use EventHandlers.

In my case, I needed Velocity calls "getAsString" instead of toString method for all JsonPrimitive objects from gson library every time that a reference was inserted.

It was as simple as creating a

public class JsonPrimitiveReferenceInsertionEventHandler implements ReferenceInsertionEventHandler{

    /* (non-Javadoc)
     * @see org.apache.velocity.app.event.ReferenceInsertionEventHandler#referenceInsert(java.lang.String, java.lang.Object)
     */
    @Override
    public Object referenceInsert(String reference, Object value) {
        if (value != null && value instanceof JsonPrimitive){
            return ((JsonPrimitive)value).getAsString();
        }
        return value;
    }

}

And add the event to the VelocityContext

vec = new EventCartridge();
vec.addEventHandler(new JsonPrimitiveReferenceInsertionEventHandler());

...

context.attachEventCartridge(vec);