我不知道在Velocity中是否有办法做到这一点:
我有一个用户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; }
而状态是静态的内部类:
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 }
使用这种模式,用户状态可以很容易地在条件中进行测试
if(User.Status.ADMIN.equals(user.getStatus())) ...
…而不必引用状态ID,任何魔术数字等的任何常量.
但是,我不知道如何使用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
但是这会抛出一个异常,看起来像是org.apache.velocity.exception.ParseErrorException:在webpages / include / dashboard.inc中遇到“User”[第10行,第21列]期望的是:“[”…“
从the VTL User Guide起,没有提到在VTL中直接访问Java类/静态成员,似乎条件的右侧(RHS)只能是数字文字,字符串文字,属性引用或方法引用.
那么有什么办法可以访问Velocity模板中的静态Java属性/引用吗?我知道作为解决方法,我可以在我的控制器中嵌入状态ID或其他标识符作为参考(这是使用Velocity作为View技术的Web MVC应用程序),但是我强烈不想嵌入任何魔术视图层中的数字或常量.
解决方法
我想出了一个解决方法,允许我将每个User.Status对象添加到Velocity上下文中,避免了对模板中的常量或魔术数字的任何引用.
在控制器/ 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);
然后在模板中,这些值可以这样引用:
#if($user.status == $statusmap.user) You are a regular user #elseif($user.status == $statusmap.admin) You are an administrator ##etc... #end