代码之家  ›  专栏  ›  技术社区  ›  matt b

如何访问速度模板中的静态成员?

  •  10
  • matt b  · 技术社区  · 16 年前

    我不确定是否有一种方法可以在速度方面做到这一点:

    我有一个用户Pojo,它是一个名为Stand的属性,它看起来像一个枚举(但是它不是,因为我被困在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的速度模板中找到如何测试这些条件的方法。我只想根据用户的状态打印一个简单的字符串,例如:

    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: Encountered "User" at webpages/include/dashboard.inc[line 10, column 21] Was expecting one of: "[" ...

    the VTL User Guide 没有提到在VTL中直接访问Java类/静态成员,看来条件的右侧(RHS)只能是数字文字、字符串文字、属性引用或方法引用。

    那么,有什么方法可以访问速度模板中的静态Java属性/引用呢?我知道作为一个解决方案,我可以在控制器中嵌入状态ID或其他标识符作为引用(这是一个使用Velocity作为视图技术的Web MVC应用程序),但我强烈不希望在视图层中嵌入任何幻数或常量。

    3 回复  |  直到 14 年前
        1
  •  8
  •   matt b    16 年前

    我想出了一个解决方法,允许我添加 User.Status 对象到速度上下文,这避免了对模板中常量或幻数的任何引用。

    在控制器/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
    
        2
  •  6
  •   Nathan Bubna    16 年前

    是的,Velocity不会在本地搜索类和包。您可以做您所做的,或者使用FieldMethodizer类来实现自动化。另一个选项是velocitytools 2.0中的fieldtool。

        3
  •  3
  •   rresino    14 年前

    尝试使用速度的FieldMethodizer,这不是最好的解决方案,但是你可以做些什么。

    使用这个类,您可以调用静态公共常量,请参见链接:

    FieldMethodizer API