26

Can you call class methods from inside a view page?

Specifically ones that are not passed into the view?

In asp.net MVC I can do this:

<%= SomeClass.FixDateFormat(ViewData.Model.SomeClass.DateCreated) %>
skaffman
  • 398,947
  • 96
  • 818
  • 769
Blankman
  • 259,732
  • 324
  • 769
  • 1,199

2 Answers2

28

Since this came up in the top of my google search on this topic it seems like folks might like to see an updated answer when they get this on the top of their search...

(found this here: http://velocity.10973.n7.nabble.com/Use-of-static-functions-td15126.html)

in Velocity 1.5 or earlier, you can just use:

#set( $String = '' )
#set( $foo = $String.format('%.1f', $dataFedIn) )

because you can always call static methods on instances. :)

however, since there are some static classes of which you cannot create instances (e.g. java.util.Math), we added support in 1.6 for static class methods sans instances:

Java:

context.put("String", String.class);

Velocity:

#set( $foo = $String.format('%.1f', $dataFedIn) ) 
Gus
  • 6,719
  • 6
  • 37
  • 58
  • 2
    Gus, you and http://velocity.apache.org/engine/devel/apidocs/org/apache/velocity/app/FieldMethodizer.html both mysteriously mention `context.put()` in Java, but I've spent an hour trying to figure out what that means and how in my Spring MVC controller I can do something like that. Where does "context" get defined? What class is it? Thanks! – Ryan Aug 15 '13 at 23:37
  • 1
    I can't speak to your particular spring setup, but in both cases context is an instance of `VelocityContext` http://velocity.apache.org/engine/releases/velocity-1.7/developer-guide.html#How_Velocity_Works – Gus Aug 16 '13 at 15:48
  • Thanks Gus. I still couldn't figure out how to use that in my Spring MVC controller, but this worked: `final String constantsClassNameString = TranslationConstants.class .getCanonicalName(); modelAndView.getModel().put(FormConstants.TRANSLATION_CONSTANTS, new FieldMethodizer(constantsClassNameString));` – Ryan Aug 16 '13 at 16:48
15

Here is a universal way to call any static method of any class without need for preliminarily context manipulation:

#‌​set($str='test')##
#set($Base64=$str.class.forName('java‌​.util.Base64'))##
​$Base64.getEncoder()‌​.encodeToString($str‌​.getBytes('utf8'))
Vadzim
  • 24,954
  • 11
  • 143
  • 151
  • 2
    This looks like it should work, but use of `Class.forName()` always has the drawback of creating dependencies on classes that are invisible at compile time, and don't break until runtime. Not a big deal for public classes in the JDK, but a potential pain point for classes that could possibly not be on the class path at a later date. For example classes that get renamed, or classes that are sub-dependencies of some dependency you stop using at a later date. – Gus Oct 20 '16 at 12:19
  • How about System.getenv()? Is there a way to invoke it via this hacky solution? – Aleksandr Kravets Apr 25 '17 at 13:00
  • @AleksandrKravets, it should work just the same as both `Base64.getEncoder()‌​` and `System.getenv()` are public static methods of uninstantiable classes. And it really does work with latest velocity 1.7 in my case. You can also try to [call static method via reflection](http://stackoverflow.com/questions/2467544/invoking-a-static-method-using-reflection) as last resort. – Vadzim Apr 25 '17 at 13:33
  • @Vadzim I just realized that maven-archetype-plugin I use is version 2.4(marked latest in maven central repo). But actual latest version is 3.0.1. And for me this means leap from Velocity 1.5 to 1.7. On 1.5 your example does not work. Thanks for response anyway. – Aleksandr Kravets Apr 26 '17 at 14:07
  • @Aleksandr, calling static methods is supported since velocity 1.6 as upper unswer states. 1.5 could be worked around only with reflection. – Vadzim Apr 26 '17 at 14:48
  • 2
    @Vadzim Thanks, it saved my day I had no access to the generator java and was wondering how to generate uuids from the template. – Franck LEVEQUE Feb 08 '19 at 12:45
  • 2
    Instead of create new variable of type `String` like `set($String='')` according to the [answer](https://community.atlassian.com/t5/Answers-Developer-Questions/Re-Access-pageManager-from-velocity/qaq-p/478628/comment-id/16283#M16283) you may use just like `#set($Base64=$content.class.forName('java‌​.util.Base64'))` – Hubbitus Feb 10 '20 at 14:50