Velocityテンプレートの静的メンバーにアクセスする方法は?
-
19-08-2019 - |
質問
Velocityでこれを行う方法があるかどうかわかりません:
列挙型のように見えるStatusという名前のプロパティを持つユーザーPOJOがありますが(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;
}
そして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: Encountered "User" at webpages/include/dashboard.inc[line 10, column 21] Was expecting one of: "[" ...
VTLユーザーガイドから、 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
他のヒント
はい、Velocityはクラスとパッケージをネイティブにgrokしません。あなたがしたことをするか、FieldMethodizerクラスを使用してそれを自動化することができます。別のオプションは、VelocityTools 2.0のFieldToolです。
VelocityのFieldMethodizerを使用してみてください。これは最良のソリューションではありませんが、何かを行うことができます。
このクラスを使用すると、静的パブリック定数を呼び出すことができます。リンクをご覧ください: