1

JspFragmentを使用してテンプレートを定義したいと思います。そのため、次のTagクラスを作成しました。

public class CreateTemplateTag extends SimpleTagSupport {

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void setJspBody(JspFragment jspBody) {
        // Reqister "body" in Template-Registry to use it later on ..
        TemplateRegistry.put(getJspContext(), name, jspBody);
    }
}

上記のクラスは、JspFragment(その本体に対応)を「グローバル」レジストリに格納するだけです。次に、以前に保存されたテンプレートを評価してページに書き込むタグを作成しました。

public class UseTemplateTag extends SimpleTagSupport {

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void doTag() throws JspException, IOException {
        JspContext ctx = getJspContext();
        ctx.getOut().write(TemplateRegistry.evaluate(ctx, name));
    }
}

レジストリは非常に単純な実装です。

public class TemplateRegistry {
    private static final String REGISTRY_KEY = "__TPL_REG__";

    public static void put(JspContext ctx, String name, JspFragment frag) {
        HashMap attribute = (HashMap) ctx.getAttribute(REGISTRY_KEY);
        if(attribute==null) {
            attribute = new HashMap();
            ctx.setAttribute(REGISTRY_KEY,attribute);
        }
        attribute.put(name, frag);
    }

    public static String evaluate(JspContext ctx, String name) {
        HashMap attribute = (HashMap) ctx.getAttribute(REGISTRY_KEY);
        if(attribute!=null) {
            try {
                JspFragment frag = (JspFragment) attribute.get(name);
                StringWriter writer = new StringWriter();
                StringBuffer sb = writer.getBuffer();
                frag.invoke(writer);
                writer.flush();
                return sb.toString();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

ご覧のとおり、レジストリは、evaluateメソッドが呼び出されるたびに適切なJspFragmentを評価します。

私が使用したJSPコードは次のとおりです。

...

<util:CreateTemplate name="xxx">
 <custom:myTag attr="${var}"/>
 This is ${var}
</util:CreateTemplate>

...

<c:forEach var="var" items="${someStringCollection}">
 <util:UseTemplate name="xxx"/>
</c:forEach>

これは非常にうまく機能しますが、これが許可されているかどうかわかりませんか?より良いアプローチはありますか?

4

1 に答える 1