I'm not sure if there is a way to do this in Velocity or not:
我不确定是否有办法在Velocity中执行此操作:
I have a User POJO which a property named Status, which looks like an enum (but it is not, since I am stuck on Java 1.4), the definition looks something like this:
我有一个用户POJO,其中一个名为Status的属性,看起来像一个枚举(但它不是,因为我被困在Java 1.4上),定义看起来像这样:
public class User {
// default status to User
private Status status = Status.USER;
public void setStatus(Status status) {
this.status = status;
}
public Status getStatus() {
return status;
}
And Status is a static inner class:
而Status是一个静态的内部类:
public static final class Status {
private String statusString;
private Status(String statusString) {
this.statusString = statusString;
}
public final static Status USER = new Status("user");
public final static Status ADMIN = new Status("admin");
public final static Status STATUS_X = new Status("blah");
//.equals() and .hashCode() implemented as well
}
With this pattern, a user status can easily be tested in a conditional such as
使用此模式,可以在诸如的条件下轻松地测试用户状态
if(User.Status.ADMIN.equals(user.getStatus())) ...
... without having to reference any constants for the status ID, any magic numbers, etc.
...无需引用状态ID的任何常量,任何幻数等。
However, I can't figure out how to test these conditionals in my Velocity template with VTL. I'd like to just print a simple string based upon the user's status, such as:
但是,我无法弄清楚如何使用VTL在Velocity模板中测试这些条件。我想根据用户的状态打印一个简单的字符串,例如:
Welcome <b>${user.name}</b>!
<br/>
<br/>
#if($user.status == com.company.blah.User.Status.USER)
You are a regular user
#elseif($user.status == com.company.blah.User.Status.ADMIN)
You are an administrator
#etc...
#end
But this throws an Exception that looks like org.apache.velocity.exception.ParseErrorException: Encountered "User" at webpages/include/dashboard.inc[line 10, column 21] Was expecting one of: "[" ...
但是这会抛出一个看起来像org.apache.velocity.exception.ParseErrorException的异常:在webpages / include / dashboard.inc遇到“User”[第10行,第21列]期待其中一个:“[”...
From the VTL User Guide, there is no mention of accessing a Java class/static member directly in VTL, it appears that the right hand side (RHS) of a conditional can only be a number literal, string literal, property reference, or method reference.
从VTL用户指南中,没有提到直接在VTL中访问Java类/静态成员,看起来条件的右侧(RHS)只能是数字文字,字符串文字,属性引用或方法参考。
So is there any way that I can access static Java properties/references in a Velocity template? I'm aware that as a workaround, I could embed the status ID or some other identifier as a reference in my controller (this is a web MVC application using Velocity as the View technology), but I strongly do not want to embed any magic numbers or constants in the view layer.
那么有什么办法可以在Velocity模板中访问静态Java属性/引用吗?我知道作为一种解决方法,我可以在我的控制器中嵌入状态ID或其他标识符作为参考(这是一个使用Velocity作为View技术的web MVC应用程序),但我强烈不想嵌入任何魔法视图层中的数字或常量。
3 个解决方案
#1
I figured out a workaround that allows me to add each User.Status
object to the Velocity context, which avoids any sort of references to constants or magic numbers in the template.
我找到了一个解决方法,允许我将每个User.Status对象添加到Velocity上下文,这避免了模板中对常量或幻数的任何类型的引用。
On the controller/Java side:
在控制器/ Java端:
// put the statuses directly into the model
Map statusMap = new HashMap();
statusMap.put("user", User.Status.USER);
statusMap.put("groupOperator", User.Status.ADMIN);
...
modelAndView.addObject("statusmap", statusMap);
And then in the template these values can be referenced like so:
然后在模板中可以像这样引用这些值:
#if($user.status == $statusmap.user)
You are a regular user
#elseif($user.status == $statusmap.admin)
You are an administrator
##etc...
#end
#2
Yeah, Velocity doesn't natively grok classes and packages. You could do what you did, or use the FieldMethodizer class to automate that. Another option would be the FieldTool in VelocityTools 2.0.
是的,Velocity本身并没有学习类和包。您可以执行您所做的操作,或使用FieldMethodizer类自动执行该操作。另一种选择是VelocityTools 2.0中的FieldTool。
#3
Try to use FieldMethodizer of Velocity, it's not the best solution but you can do something.
尝试使用Velocity的FieldMethodizer,它不是最好的解决方案,但你可以做点什么。
With this class you can call to static public constants, please see the link:
使用此类,您可以调用静态公共常量,请参阅链接:
#1
I figured out a workaround that allows me to add each User.Status
object to the Velocity context, which avoids any sort of references to constants or magic numbers in the template.
我找到了一个解决方法,允许我将每个User.Status对象添加到Velocity上下文,这避免了模板中对常量或幻数的任何类型的引用。
On the controller/Java side:
在控制器/ Java端:
// put the statuses directly into the model
Map statusMap = new HashMap();
statusMap.put("user", User.Status.USER);
statusMap.put("groupOperator", User.Status.ADMIN);
...
modelAndView.addObject("statusmap", statusMap);
And then in the template these values can be referenced like so:
然后在模板中可以像这样引用这些值:
#if($user.status == $statusmap.user)
You are a regular user
#elseif($user.status == $statusmap.admin)
You are an administrator
##etc...
#end
#2
Yeah, Velocity doesn't natively grok classes and packages. You could do what you did, or use the FieldMethodizer class to automate that. Another option would be the FieldTool in VelocityTools 2.0.
是的,Velocity本身并没有学习类和包。您可以执行您所做的操作,或使用FieldMethodizer类自动执行该操作。另一种选择是VelocityTools 2.0中的FieldTool。
#3
Try to use FieldMethodizer of Velocity, it's not the best solution but you can do something.
尝试使用Velocity的FieldMethodizer,它不是最好的解决方案,但你可以做点什么。
With this class you can call to static public constants, please see the link:
使用此类,您可以调用静态公共常量,请参阅链接: