ゴミ箱.net

汚物は消毒

Struts 2でeval関数もどきを実現するウルテク

Struts 2はOGNL を式解析器として利用することで、異様に柔軟なページ作成を可能にしている。

たとえばJSPをビュートして用いる場合、JSPファイルに以下のようなタグを書く。(JSPの先頭で<%@ taglib prefix="s" uri="/struts-tags" %>のようにディレクティブを定義しておいてね。)

<s:property value="hoge * 2" />

このように書くと、ビューを呼び出したアクションのクラスに定義されたメソッドgetHoge()を呼び出してその値を取得し、その値の2倍をタグの箇所に勝手に埋め込んでくれる。getHoge()の戻り値が3ならば、タグの箇所に「6」と記載される。
ここで、計算式そのものはただの文字列であり、事前にコンパイルされたものではないことに注意。OGNLに式の文字列を渡すことで式を実行時に解析して計算してくれているのだ。
この仕組みによって、Struts 2はビューにある程度の処理を組み込むことができるようになっており、本当のロジックに表示のためだけの煩雑な処理をあまり入れなくてすむようになっている。

ただ、この式そのものを実行時に組み立てることは、普通はできない。JSPタグの属性として事前にハードコーディングする必要があるのだ。
アクションのクラスに定義した文字列を返すgetterや、Struts 2のタグ<s:set>などにより、変数として文字列を与えても、与えた文字列がそのまま表示されるだけで文字列を式として評価させることはできない。
EL式を使って逃げようと思っても、Struts 2のタグは普通のJSPライブラリのタグと違い、EL式を一切受け付けません。(${変数名}のようなEL式を含めるとエラーになる。)
JavaScriptのeval関数のように、動的に組み立てた文字列を式として評価することがどうしてもできないのだ。必要なことはあまりないが、まれにこのような処理がどうしても必要なことがあって非常に困る。
これもフレームワークのサガか…

…とここで終わるのが凡人の悲しいサガ。Strutsを極めればこの程度のことなど造作もない。

ビューを呼び出すアクションに以下のようなメソッドを定義してください。import宣言はお好みで。

import com.opensymphony.xwork2.ActionContext;

//アクションクラス
public class HogeAction {
(ry

    //JavaScriptのeval関数もどき
public Object eval(String s) {
return ActionContext.getContext().getValueStack().findValue(s);
}
}

ビューのJSPファイルにおいて以下のように呼び出すことができます。

<s:property value="eval('1 + 1 == 2')" />

上の例だと固定文字列なのでまったくありがたみがないが…w

<s:property value="eval(hoge)" />

のように記述し、アクションに文字列を返すメソッドgetHoge()を定義しておくと、getHoge()の戻り値を式として実行時に解釈してくれるようになります。
eval()に渡す文字列の中でさらに変数やメソッドを指定することもできるようです。Struts 2のタグ<s:set>によってビュー内部で定義した変数も呼び出せる模様。

まさにJavaScriptのeval関数もどき。
スポンサーサイト

PageTop

コメント


管理者にだけ表示を許可する