在Velocity视图页面中调用类方法(静态方法)

26

你能否从视图页面内部调用类方法?

具体而言,这些方法没有被传递到视图中吗?

在ASP.NET MVC中,我可以这样做:

<%= SomeClass.FixDateFormat(ViewData.Model.SomeClass.DateCreated) %>
2个回答

28

由于这个问题在我谷歌搜索的顶部出现,似乎大家会希望看到一个更新的答案,当他们在搜索时找到这篇文章...

(在这里找到了这个链接: http://velocity.10973.n7.nabble.com/Use-of-static-functions-td15126.html)

在Velocity 1.5或更早版本中,你可以直接使用:

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

因为你总是可以在实例上调用静态方法。 :)
然而,由于有一些静态类不能创建实例(例如java.util.Math),因此我们在1.6中添加了对没有实例的静态类方法的支持:
Java:
context.put("String", String.class);

速度:

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

2
Gus,你和http://velocity.apache.org/engine/devel/apidocs/org/apache/velocity/app/FieldMethodizer.html都神秘地提到了Java中的`context.put()`,但我已经花了一个小时试图弄清楚这意味着什么以及在我的Spring MVC控制器中如何做类似的事情。 "context"在哪里定义? 它是什么类?谢谢! - Ryan
1
我无法了解你的Spring设置情况,但在这两种情况下,上下文都是 VelocityContext 的一个实例。http://velocity.apache.org/engine/releases/velocity-1.7/developer-guide.html#How_Velocity_Works - Gus
谢谢 Gus。我仍然无法弄清如何在我的Spring MVC控制器中使用它,但这个可以:final String constantsClassNameString = TranslationConstants.class .getCanonicalName(); modelAndView.getModel().put(FormConstants.TRANSLATION_CONSTANTS, new FieldMethodizer(constantsClassNameString)); - Ryan

15

下面是一种通用的方式,无需预处理上下文即可调用任何类的任何静态方法:

#‌​set($str='test')##
#set($Base64=$str.class.forName('java‌​.util.Base64'))##
​$Base64.getEncoder()‌​.encodeToString($str‌​.getBytes('utf8'))

2
这看起来应该可以工作,但使用Class.forName()总是存在一个缺点,即在编译时创建对不可见类的依赖关系,直到运行时才会出现问题。对于JDK中的公共类来说并不是什么大问题,但对于可能在以后的某个日期不在类路径上的类来说,这可能是一个潜在的痛点。例如,被重命名的类或是某些您在以后不再使用的依赖项的子依赖项的类。 - Gus
System.getenv()怎么样?有没有办法通过这种hacky解决方案来调用它? - Aleksandr Kravets
@AleksandrKravets,它应该与Base64.getEncoder()System.getenv()一样工作,因为它们都是不可实例化类的公共静态方法。在我的情况下,最新的velocity 1.7确实可以工作。您还可以尝试通过反射调用静态方法作为最后的手段。 - Vadzim
2
@Vadzim 谢谢,救了我的一天!我无法访问生成器Java,不知道如何从模板中生成UUID。 - Franck LEVEQUE
2
根据答案,您可以使用#set($Base64=$content.class.forName('java.util.Base64')),而不是创建类型为String的新变量,例如set($String='') - Hubbitus
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接